Halide
FunctionDAG.h
Go to the documentation of this file.
1 /** This file defines the class FunctionDAG, which is our
2  * representation of a Halide pipeline, and contains methods to using
3  * Halide's bounds tools to query properties of it. */
4 
5 #ifndef FUNCTION_DAG_H
6 #define FUNCTION_DAG_H
7 
8 #include <algorithm>
9 #include <cstdint>
10 #include <map>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "Errors.h"
16 #include "Featurization.h"
17 #include "Halide.h"
18 #include "PerfectHashMap.h"
19 
20 namespace Halide {
21 namespace Internal {
22 namespace Autoscheduler {
23 
24 using std::map;
25 using std::pair;
26 using std::string;
27 using std::unique_ptr;
28 using std::vector;
29 
30 // First we have various utility classes.
31 
32 // An optional rational type used when analyzing memory dependencies.
33 struct OptionalRational {
35 
36  bool exists() const {
37  return denominator != 0;
38  }
39 
40  OptionalRational() = default;
42  : numerator(n), denominator(d) {
43  }
44 
45  void operator+=(const OptionalRational &other) {
46  if ((denominator & other.denominator) == 0) {
47  numerator = denominator = 0;
48  return;
49  }
50  if (denominator == other.denominator) {
51  numerator += other.numerator;
52  return;
53  }
54 
55  int64_t l = lcm(denominator, other.denominator);
56  numerator *= l / denominator;
57  denominator = l;
58  numerator += other.numerator * (l / other.denominator);
60  numerator /= g;
61  denominator /= g;
62  }
63 
65  if ((*this) == 0) {
66  return *this;
67  }
68  int64_t num = numerator * factor;
69  return OptionalRational{num, denominator};
70  }
71 
73  if ((*this) == 0) {
74  return *this;
75  }
76  if (other == 0) {
77  return other;
78  }
79  int64_t num = numerator * other.numerator;
80  int64_t den = denominator * other.denominator;
81  return OptionalRational{num, den};
82  }
83 
84  // Because this type is optional (exists may be false), we don't
85  // have a total ordering. These methods all return false when the
86  // operators are not comparable, so a < b is not the same as !(a
87  // >= b).
88  bool operator<(int x) const {
89  if (denominator == 0) {
90  return false;
91  } else if (denominator > 0) {
92  return numerator < x * denominator;
93  } else {
94  return numerator > x * denominator;
95  }
96  }
97 
98  bool operator<=(int x) const {
99  if (denominator == 0) {
100  return false;
101  } else if (denominator > 0) {
102  return numerator <= x * denominator;
103  } else {
104  return numerator >= x * denominator;
105  }
106  }
107 
108  bool operator>(int x) const {
109  if (!exists()) {
110  return false;
111  }
112  return !((*this) <= x);
113  }
114 
115  bool operator>=(int x) const {
116  if (!exists()) {
117  return false;
118  }
119  return !((*this) < x);
120  }
121 
122  bool operator==(int x) const {
123  return exists() && (numerator == (x * denominator));
124  }
125 
126  bool operator==(const OptionalRational &other) const {
127  return (exists() == other.exists()) && (numerator * other.denominator == denominator * other.numerator);
128  }
129 };
130 
131 // A LoadJacobian records the derivative of the coordinate accessed in
132 // some producer w.r.t the loops of the consumer.
133 class LoadJacobian {
134  std::vector<OptionalRational> coeffs;
135  int64_t c;
136  size_t rows, cols;
137 
138 public:
140  : c(count), rows(producer_storage_dims), cols(consumer_loop_dims) {
141  coeffs.resize(rows * cols);
142  }
143 
144  bool all_coeffs_exist() const {
145  for (const auto &coeff : coeffs) {
146  if (!coeff.exists()) {
147  return false;
148  }
149  }
150  return true;
151  }
152 
153  bool empty() const {
154  return rows == 0;
155  }
156 
157  size_t producer_storage_dims() const {
158  return rows;
159  }
160 
161  size_t consumer_loop_dims() const {
162  return cols;
163  }
164 
165  bool is_constant() const {
166  for (const auto &c : coeffs) {
167  if (!c.exists() || !(c == 0)) {
168  return false;
169  }
170  }
171 
172  return true;
173  }
174 
175  OptionalRational operator()(int producer_storage_dim, int consumer_loop_dim) const {
176  if (producer_storage_dims() == 0 || consumer_loop_dims() == 0) {
177  // The producer or consumer is scalar, so all strides are zero.
178  return {0, 1};
179  }
180  return coeffs[producer_storage_dim * cols + consumer_loop_dim];
181  }
182 
183  OptionalRational &operator()(int producer_storage_dim, int consumer_loop_dim) {
184  return coeffs[producer_storage_dim * cols + consumer_loop_dim];
185  }
186 
187  // To avoid redundantly re-recording copies of the same
188  // load Jacobian, we keep a count of how many times a
189  // load with this Jacobian occurs.
190  int64_t count() const {
191  return c;
192  }
193 
194  // Try to merge another LoadJacobian into this one, increasing the
195  // count if the coefficients match.
196  bool merge(const LoadJacobian &other) {
197  if (other.rows != rows || other.cols != cols) {
198  return false;
199  }
200  for (size_t i = 0; i < rows * cols; i++) {
201  if (!(other.coeffs[i] == coeffs[i])) {
202  return false;
203  }
204  }
205  c += other.count();
206  return true;
207  }
208 
209  // Scale the matrix coefficients by the given factors
210  LoadJacobian operator*(const std::vector<int64_t> &factors) const {
211  LoadJacobian result(rows, cols, c);
212  for (size_t i = 0; i < producer_storage_dims(); i++) {
213  for (size_t j = 0; j < consumer_loop_dims(); j++) {
214  result(i, j) = (*this)(i, j) * factors[j];
215  }
216  }
217  return result;
218  }
219 
220  // Multiply Jacobians, used to look at memory dependencies through
221  // inlined functions.
222  LoadJacobian operator*(const LoadJacobian &other) const {
223  LoadJacobian result(producer_storage_dims(), other.consumer_loop_dims(), count() * other.count());
224  for (size_t i = 0; i < producer_storage_dims(); i++) {
225  for (size_t j = 0; j < other.consumer_loop_dims(); j++) {
226  result(i, j) = OptionalRational{0, 1};
227  for (size_t k = 0; k < consumer_loop_dims(); k++) {
228  result(i, j) += (*this)(i, k) * other(k, j);
229  }
230  }
231  }
232  return result;
233  }
234 
235  void dump(const char *prefix) const;
236 };
237 
238 // Classes to represent a concrete set of bounds for a Func. A Span is
239 // single-dimensional, and a Bound is a multi-dimensional box. For
240 // each dimension we track the estimated size, and also whether or not
241 // the size is known to be constant at compile-time. For each Func we
242 // track three different types of bounds:
243 
244 // 1) The region required by consumers of the Func, which determines
245 // 2) The region actually computed, which in turn determines
246 // 3) The min and max of all loops in the loop next.
247 
248 // 3 in turn determines the region required of the inputs to a Func,
249 // which determines their region computed, and hence their loop nest,
250 // and so on back up the Function DAG from outputs back to inputs.
251 
252 class Span {
253  int64_t min_, max_;
254  bool constant_extent_;
255 
256 public:
257  int64_t min() const {
258  return min_;
259  }
260  int64_t max() const {
261  return max_;
262  }
263  int64_t extent() const {
264  return max_ - min_ + 1;
265  }
266  bool constant_extent() const {
267  return constant_extent_;
268  }
269 
270  void union_with(const Span &other) {
271  min_ = std::min(min_, other.min());
272  max_ = std::max(max_, other.max());
273  constant_extent_ = constant_extent_ && other.constant_extent();
274  }
275 
276  void set_extent(int64_t e) {
277  max_ = min_ + e - 1;
278  }
279 
280  void translate(int64_t x) {
281  min_ += x;
282  max_ += x;
283  }
284 
285  Span(int64_t a, int64_t b, bool c)
286  : min_(a), max_(b), constant_extent_(c) {
287  }
288  Span() = default;
289  Span(const Span &other) = default;
290  static Span empty_span() {
291  return Span(INT64_MAX, INT64_MIN, true);
292  }
293 };
294 
295 // Bounds objects are created and destroyed very frequently while
296 // exploring scheduling options, so we have a custom allocator and
297 // memory pool. Much like IR nodes, we treat them as immutable once
298 // created and wrapped in a Bound object so that they can be shared
299 // safely across scheduling alternatives.
300 struct BoundContents {
301  mutable RefCount ref_count;
302 
303  class Layout;
304  const Layout *layout = nullptr;
305 
306  Span *data() const {
307  // This struct is a header
308  return (Span *)(const_cast<BoundContents *>(this) + 1);
309  }
310 
312  return data()[i];
313  }
314 
316  return data()[i + layout->computed_offset];
317  }
318 
319  Span &loops(int i, int j) {
320  return data()[j + layout->loop_offset[i]];
321  }
322 
323  const Span &region_required(int i) const {
324  return data()[i];
325  }
326 
327  const Span &region_computed(int i) const {
328  return data()[i + layout->computed_offset];
329  }
330 
331  const Span &loops(int i, int j) const {
332  return data()[j + layout->loop_offset[i]];
333  }
334 
336  auto *b = layout->make();
337  size_t bytes = sizeof(data()[0]) * layout->total_size;
338  memcpy(b->data(), data(), bytes);
339  return b;
340  }
341 
342  void validate() const;
343 
344  // We're frequently going to need to make these concrete bounds
345  // arrays. It makes things more efficient if we figure out the
346  // memory layout of those data structures once ahead of time, and
347  // make each individual instance just use that. Note that this is
348  // not thread-safe.
349  class Layout {
350  // A memory pool of free BoundContent objects with this layout
351  mutable std::vector<BoundContents *> pool;
352 
353  // All the blocks of memory allocated
354  mutable std::vector<void *> blocks;
355 
356  mutable size_t num_live = 0;
357 
358  void allocate_some_more() const;
359 
360  public:
361  // number of Span to allocate
362  int total_size;
363 
364  // region_computed comes next at the following index
365  int computed_offset;
366 
367  // the loop for each stage starts at the following index
368  std::vector<int> loop_offset;
369 
370  Layout() = default;
371  ~Layout();
372 
373  Layout(const Layout &) = delete;
374  void operator=(const Layout &) = delete;
375  Layout(Layout &&) = delete;
376  void operator=(Layout &&) = delete;
377 
378  // Make a BoundContents object with this layout
379  BoundContents *make() const;
380 
381  // Release a BoundContents object with this layout back to the pool
382  void release(const BoundContents *b) const;
383  };
384 };
385 
386 using Bound = IntrusivePtr<const BoundContents>;
387 
388 // A representation of the function DAG. The nodes and edges are both
389 // in reverse realization order, so if you want to walk backwards up
390 // the DAG, just iterate the nodes or edges in-order.
391 struct FunctionDAG {
392 
393  // An edge is a producer-consumer relationship
394  struct Edge;
395 
396  struct SymbolicInterval {
399  };
400 
401  // A Node represents a single Func
402  struct Node {
403  // A pointer back to the owning DAG
404  FunctionDAG *dag;
405 
406  // The Halide Func this represents
407  Function func;
408 
409  // The number of bytes per point stored.
410  double bytes_per_point;
411 
412  // The min/max variables used to denote a symbolic region of
413  // this Func. Used in the cost above, and in the Edges below.
414  vector<SymbolicInterval> region_required;
415 
416  // A concrete region required from a bounds estimate. Only
417  // defined for outputs.
418  vector<Span> estimated_region_required;
419 
420  // The region computed of a Func, in terms of the region
421  // required. For simple Funcs this is identical to the
422  // region_required. However, in some Funcs computing one
423  // output requires computing other outputs too. You can't
424  // really ask for a single output pixel from something blurred
425  // with an IIR without computing the others, for example.
426  struct RegionComputedInfo {
427  // The min and max in their full symbolic glory. We use
428  // these in the general case.
429  Interval in;
430 
431  // Analysis used to accelerate common cases
433  int64_t c_min = 0, c_max = 0;
434  };
435  vector<RegionComputedInfo> region_computed;
437 
438  // Expand a region required into a region computed, using the
439  // symbolic intervals above.
440  void required_to_computed(const Span *required, Span *computed) const;
441 
442  // Metadata about one symbolic loop in a Func's default loop nest.
443  struct Loop {
444  string var;
445  bool pure, rvar;
446  Expr min, max;
447 
448  // Which pure dimension does this loop correspond to? Invalid if it's an rvar
449  int pure_dim;
450 
451  // Precomputed metadata to accelerate common cases:
452 
453  // If true, the loop bounds are just the region computed in the given dimension
454  bool equals_region_computed = false;
455  int region_computed_dim = 0;
456 
457  // If true, the loop bounds are a constant with the given min and max
458  bool bounds_are_constant = false;
459  int64_t c_min = 0, c_max = 0;
460 
461  // A persistent fragment of source for getting this Var
462  // from its owner Func. Used for printing source code
463  // equivalent to a computed schedule.
464  string accessor;
465  };
466 
467  // Get the loop nest shape as a function of the region computed
468  void loop_nest_for_region(int stage_idx, const Span *computed, Span *loop) const;
469 
470  // One stage of a Func
471  struct Stage {
472  // The owning Node
473  Node *node;
474 
475  // Which stage of the Func is this. 0 = pure.
476  int index;
477 
478  // The loop nest that computes this stage, from innermost out.
479  vector<Loop> loop;
480  bool loop_nest_all_common_cases = false;
481 
482  // The vectorization width that will be used for
483  // compute. Corresponds to the natural width for the
484  // narrowest type used.
485  int vector_size;
486 
487  // The featurization of the compute done
488  PipelineFeatures features;
489 
490  // The actual Halide front-end stage object
492 
493  // The name for scheduling (e.g. "foo.update(3)")
494  string name;
495 
497 
498  // Ids for perfect hashing on stages.
499  int id, max_id;
500 
501  std::unique_ptr<LoadJacobian> store_jacobian;
502 
503  vector<Edge *> incoming_edges;
504 
505  vector<bool> dependencies;
506  bool downstream_of(const Node &n) const {
507  return dependencies[n.id];
508  };
509 
511  : stage(std::move(s)) {
512  }
513 
514  int get_loop_index_from_var(const std::string &var) const {
515  int i = 0;
516  for (const auto &l : loop) {
517  if (l.var == var) {
518  return i;
519  }
520 
521  ++i;
522  }
523 
524  return -1;
525  }
526  };
527  vector<Stage> stages;
528 
529  vector<Edge *> outgoing_edges;
530 
531  // Max vector size across the stages
532  int vector_size;
533 
534  // A unique ID for this node, allocated consecutively starting
535  // at zero for each pipeline.
536  int id, max_id;
537 
538  // Just func->dimensions(), but we ask for it so many times
539  // that's it's worth avoiding the function call into
540  // libHalide.
541  int dimensions;
542 
543  // Is a single pointwise call to another Func
544  bool is_wrapper;
545 
546  // We represent the input buffers as node, though we do not attempt to schedule them.
547  bool is_input;
548 
549  // Is one of the pipeline outputs
550  bool is_output;
551 
552  // Only uses pointwise calls
553  bool is_pointwise;
554 
555  // Only uses pointwise calls + clamping on all indices
557 
558  std::unique_ptr<BoundContents::Layout> bounds_memory_layout;
559 
561  return bounds_memory_layout->make();
562  }
563  };
564 
565  // A representation of a producer-consumer relationship
566  struct Edge {
567  struct BoundInfo {
568  // The symbolic expression for the bound in this dimension
569  Expr expr;
570 
571  // Fields below are the results of additional analysis
572  // used to evaluate this bound more quickly.
575  bool affine, uses_max;
576 
577  BoundInfo(const Expr &e, const Node::Stage &consumer);
578  };
579 
580  // Memory footprint on producer required by consumer.
581  vector<pair<BoundInfo, BoundInfo>> bounds;
582 
583  FunctionDAG::Node *producer;
584  FunctionDAG::Node::Stage *consumer;
585 
586  // The number of calls the consumer makes to the producer, per
587  // point in the loop nest of the consumer.
588  int calls;
589 
590  bool all_bounds_affine;
591 
592  vector<LoadJacobian> load_jacobians;
593 
594  bool all_load_jacobian_coeffs_exist() const;
595 
596  void add_load_jacobian(LoadJacobian j1);
597 
598  // Given a loop nest of the consumer stage, expand a region
599  // required of the producer to be large enough to include all
600  // points required.
601  void expand_footprint(const Span *consumer_loop, Span *producer_required) const;
602  };
603 
604  vector<Node> nodes;
605  vector<Edge> edges;
606 
608 
609  // We're going to be querying this DAG a lot while searching for
610  // an optimal schedule, so we'll also create a variety of
611  // auxiliary data structures.
612  map<int, const Node *> stage_id_to_node_map;
613 
614  // Create the function DAG, and do all the dependency and cost
615  // analysis. This is done once up-front before the tree search.
616  FunctionDAG(const vector<Function> &outputs, const Target &target);
617 
618  void dump() const;
619  std::ostream &dump(std::ostream &os) const;
620 
621  // This class uses a lot of internal pointers, so we'll hide the copy constructor.
622  FunctionDAG(const FunctionDAG &other) = delete;
623  void operator=(const FunctionDAG &other) = delete;
624 
625 private:
626  // Compute the featurization for the entire DAG
627  void featurize();
628 
629  template<typename OS>
630  void dump_internal(OS &os) const;
631 };
632 
633 template<typename T>
635 
636 class ExprBranching : public VariadicVisitor<ExprBranching, int, int> {
638 
639 private:
640  const NodeMap<int64_t> &inlined;
641 
642 public:
643  int visit(const Reinterpret *op);
644  int visit(const IntImm *op);
645  int visit(const UIntImm *op);
646  int visit(const FloatImm *op);
647  int visit(const StringImm *op);
648  int visit(const Broadcast *op);
649  int visit(const Cast *op);
650  int visit(const Variable *op);
651  int visit(const Add *op);
652  int visit(const Sub *op);
653  int visit(const Mul *op);
654  int visit(const Div *op);
655  int visit(const Mod *op);
656  int visit(const Min *op);
657  int visit(const Max *op);
658  int visit(const EQ *op);
659  int visit(const NE *op);
660  int visit(const LT *op);
661  int visit(const LE *op);
662  int visit(const GT *op);
663  int visit(const GE *op);
664  int visit(const And *op);
665  int visit(const Or *op);
666  int visit(const Not *op);
667  int visit(const Select *op);
668  int visit(const Ramp *op);
669  int visit(const Load *op);
670  int visit(const Call *op);
671  int visit(const Shuffle *op);
672  int visit(const Let *op);
673  int visit(const VectorReduce *op);
674  int visit_binary(const Expr &a, const Expr &b);
675  int visit_nary(const std::vector<Expr> &exprs);
676 
678  : inlined{inlined} {
679  }
680 
681  int compute(const Function &f);
682 };
683 
684 void sanitize_names(std::string &str);
685 
686 } // namespace Autoscheduler
687 } // namespace Internal
688 } // namespace Halide
689 
690 #endif // FUNCTION_DAG_H
int32_t
signed __INT32_TYPE__ int32_t
Definition: runtime_internal.h:24
Halide::Internal::Autoscheduler::ExprBranching::compute
int compute(const Function &f)
Halide::Internal::Autoscheduler::LoadJacobian::count
int64_t count() const
Definition: FunctionDAG.h:167
Halide::Internal::Autoscheduler::LoadJacobian::LoadJacobian
LoadJacobian(size_t producer_storage_dims, size_t consumer_loop_dims, int64_t count)
Definition: FunctionDAG.h:139
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::coeff
int64_t coeff
Definition: FunctionDAG.h:534
Halide::Internal::Add
The sum of two expressions.
Definition: IR.h:48
Halide::Internal::Autoscheduler::OptionalRational::operator>
bool operator>(int x) const
Definition: FunctionDAG.h:108
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::index
int index
Definition: FunctionDAG.h:454
Halide::Internal::Autoscheduler::BoundContents
Definition: FunctionDAG.h:275
Errors.h
Halide::Var
A Halide variable, to be used when defining functions.
Definition: Var.h:19
Halide::Internal::Autoscheduler::FunctionDAG::Node::region_computed_all_common_cases
bool region_computed_all_common_cases
Definition: FunctionDAG.h:414
Halide::Internal::Autoscheduler::FunctionDAG::Node::vector_size
int vector_size
Definition: FunctionDAG.h:493
Halide::Internal::Autoscheduler::FunctionDAG::nodes
vector< Node > nodes
Definition: FunctionDAG.h:563
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::dependencies
vector< bool > dependencies
Definition: FunctionDAG.h:479
Halide::Internal::Autoscheduler::FunctionDAG::SymbolicInterval::min
Halide::Var min
Definition: FunctionDAG.h:374
Halide::Internal::VectorReduce
Horizontally reduce a vector to a scalar or narrower vector using the given commutative and associati...
Definition: IR.h:929
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::features
PipelineFeatures features
Definition: FunctionDAG.h:466
Halide::Internal::Autoscheduler::FunctionDAG::Node::bytes_per_point
double bytes_per_point
Definition: FunctionDAG.h:387
Halide::Internal::Autoscheduler::BoundContents::make_copy
BoundContents * make_copy() const
Definition: FunctionDAG.h:335
Halide::Internal::Autoscheduler::FunctionDAG::Node::dag
FunctionDAG * dag
Definition: FunctionDAG.h:381
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::accessor
string accessor
Definition: FunctionDAG.h:442
Halide::Internal::GE
Is the first expression greater than or equal to the second.
Definition: IR.h:158
Halide::Internal::Autoscheduler::ExprBranching::ExprBranching
ExprBranching(const NodeMap< int64_t > &inlined)
Definition: FunctionDAG.h:677
Halide::Internal::Autoscheduler::LoadJacobian::operator*
LoadJacobian operator*(const std::vector< int64_t > &factors) const
Definition: FunctionDAG.h:210
Halide::Internal::Autoscheduler::BoundContents::Layout::Layout
Layout()=default
Halide::Internal::Autoscheduler::OptionalRational::numerator
int64_t numerator
Definition: FunctionDAG.h:37
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::affine
bool affine
Definition: FunctionDAG.h:536
Halide::Internal::Autoscheduler::LoadJacobian::empty
bool empty() const
Definition: FunctionDAG.h:153
Halide::min
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:584
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::pure_dim
int pure_dim
Definition: FunctionDAG.h:427
Halide::Internal::Autoscheduler::FunctionDAG
Definition: FunctionDAG.h:368
Halide::Internal::Autoscheduler::FunctionDAG::Node::outgoing_edges
vector< Edge * > outgoing_edges
Definition: FunctionDAG.h:490
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::store_jacobian
std::unique_ptr< LoadJacobian > store_jacobian
Definition: FunctionDAG.h:501
Halide::Internal::FloatImm
Floating point constants.
Definition: Expr.h:235
Halide::Internal::Autoscheduler::OptionalRational::operator+=
void operator+=(const OptionalRational &other)
Definition: FunctionDAG.h:45
Halide::Internal::Autoscheduler::BoundContents::layout
const Layout * layout
Definition: FunctionDAG.h:279
Halide::Internal::Broadcast
A vector with 'lanes' elements, in which every element is 'value'.
Definition: IR.h:251
Halide::Internal::Div
The ratio of two expressions.
Definition: IR.h:75
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::rvar
bool rvar
Definition: FunctionDAG.h:423
Halide::Internal::Autoscheduler::LoadJacobian::consumer_loop_dims
size_t consumer_loop_dims() const
Definition: FunctionDAG.h:140
Halide::Internal::Autoscheduler::LoadJacobian::all_coeffs_exist
bool all_coeffs_exist() const
Definition: FunctionDAG.h:144
Halide::Internal::IntImm
Integer constants.
Definition: Expr.h:217
Halide::Internal::Autoscheduler::FunctionDAG::Node::loop_nest_for_region
void loop_nest_for_region(int stage_idx, const Span *computed, Span *loop) const
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::equals_union_of_required_with_constants
bool equals_union_of_required_with_constants
Definition: FunctionDAG.h:410
Halide::Internal::Autoscheduler::FunctionDAG::dump
void dump() const
Halide::Internal::Autoscheduler::Span
Definition: FunctionDAG.h:227
Halide::Internal::Autoscheduler::sanitize_names
void sanitize_names(std::string &str)
Halide::Internal::Autoscheduler::BoundContents::region_computed
Span & region_computed(int i)
Definition: FunctionDAG.h:315
Halide::Internal::Autoscheduler::Span::max
int64_t max() const
Definition: FunctionDAG.h:260
Halide::Internal::Cast
The actual IR nodes begin here.
Definition: IR.h:29
Halide::Internal::LE
Is the first expression less than or equal to the second.
Definition: IR.h:140
Halide::Internal::Autoscheduler::BoundContents::Layout::make
BoundContents * make() const
Halide::Internal::Autoscheduler::FunctionDAG::FunctionDAG
FunctionDAG(const vector< Function > &outputs, const Target &target)
Halide::Internal::NE
Is the first expression not equal to the second.
Definition: IR.h:122
Halide::Internal::Autoscheduler::FunctionDAG::Edge::producer
FunctionDAG::Node * producer
Definition: FunctionDAG.h:544
Halide::Internal::Autoscheduler::Span::min
int64_t min() const
Definition: FunctionDAG.h:257
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::bounds_are_constant
bool bounds_are_constant
Definition: FunctionDAG.h:436
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::max
Expr max
Definition: FunctionDAG.h:424
Halide::Internal::Autoscheduler::BoundContents::validate
void validate() const
Halide::Internal::Autoscheduler::LoadJacobian::operator()
OptionalRational & operator()(int producer_storage_dim, int consumer_loop_dim)
Definition: FunctionDAG.h:183
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::max_id
int max_id
Definition: FunctionDAG.h:475
Halide::Internal::Autoscheduler::Span::translate
void translate(int64_t x)
Definition: FunctionDAG.h:280
Halide::Internal::gcd
int64_t gcd(int64_t, int64_t)
The greatest common divisor of two integers.
Halide::Internal::Autoscheduler::Span::empty_span
static Span empty_span()
Definition: FunctionDAG.h:290
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_input
bool is_input
Definition: FunctionDAG.h:508
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::min
Expr min
Definition: FunctionDAG.h:424
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::node
Node * node
Definition: FunctionDAG.h:451
Halide::Internal::Load
Load a value from a named symbol if predicate is true.
Definition: IR.h:209
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::Internal::Autoscheduler::FunctionDAG::operator=
FunctionDAG & operator=(const FunctionDAG &other)=delete
Halide::Internal::Autoscheduler::Span::Span
Span()=default
PerfectHashMap.h
Halide::Internal::Or
Logical or - is at least one of the expression true.
Definition: IR.h:176
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::consumer_dim
int64_t consumer_dim
Definition: FunctionDAG.h:535
Halide::Internal::EQ
Is the first expression equal to the second.
Definition: IR.h:113
Halide::Internal::Autoscheduler::OptionalRational::operator<=
bool operator<=(int x) const
Definition: FunctionDAG.h:98
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Internal::Max
The greater of two values.
Definition: IR.h:104
Halide::Internal::Autoscheduler::Bound
IntrusivePtr< const BoundContents > Bound
Definition: FunctionDAG.h:363
Halide::Internal::Autoscheduler::FunctionDAG::num_non_input_nodes
int num_non_input_nodes
Definition: FunctionDAG.h:607
Halide::Internal::Autoscheduler::LoadJacobian::operator()
OptionalRational operator()(int producer_storage_dim, int consumer_loop_dim) const
Definition: FunctionDAG.h:175
Halide::Internal::Autoscheduler::BoundContents::region_required
Span & region_required(int i)
Definition: FunctionDAG.h:311
Halide::Internal::Autoscheduler::BoundContents::Layout::operator=
void operator=(const Layout &)=delete
Halide::Internal::Autoscheduler::LoadJacobian::producer_storage_dims
size_t producer_storage_dims() const
Definition: FunctionDAG.h:136
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::sanitized_name
string sanitized_name
Definition: FunctionDAG.h:496
Halide::Internal::Autoscheduler::FunctionDAG::Node::make_bound
BoundContents * make_bound() const
Definition: FunctionDAG.h:560
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_wrapper
bool is_wrapper
Definition: FunctionDAG.h:505
Halide::Internal::Autoscheduler::FunctionDAG::SymbolicInterval::max
Halide::Var max
Definition: FunctionDAG.h:375
Halide::Internal::Let
A let expression, like you might find in a functional language.
Definition: IR.h:263
Halide::Internal::Autoscheduler::Span::extent
int64_t extent() const
Definition: FunctionDAG.h:263
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::pure
bool pure
Definition: FunctionDAG.h:423
Halide::Internal::Autoscheduler::OptionalRational::operator>=
bool operator>=(int x) const
Definition: FunctionDAG.h:115
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::Stage
Stage(Halide::Stage s)
Definition: FunctionDAG.h:510
Halide::Internal::Ramp
A linear ramp vector node.
Definition: IR.h:239
Halide::Internal::Autoscheduler::FunctionDAG::Node::stages
vector< Stage > stages
Definition: FunctionDAG.h:488
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::expr
Expr expr
Definition: FunctionDAG.h:530
Halide::Internal::Autoscheduler::BoundContents::Layout::total_size
int total_size
Definition: FunctionDAG.h:337
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::stage
Halide::Stage stage
Definition: FunctionDAG.h:469
Featurization.h
Halide::Internal::Autoscheduler::LoadJacobian::operator*
LoadJacobian operator*(const LoadJacobian &other) const
Definition: FunctionDAG.h:222
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::loop
vector< Loop > loop
Definition: FunctionDAG.h:457
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::c_min
int64_t c_min
Definition: FunctionDAG.h:411
int64_t
signed __INT64_TYPE__ int64_t
Definition: runtime_internal.h:22
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::uses_max
bool uses_max
Definition: FunctionDAG.h:536
Halide::Internal::Autoscheduler::FunctionDAG::edges
vector< Edge > edges
Definition: FunctionDAG.h:564
Halide::Internal::Autoscheduler::FunctionDAG::stage_id_to_node_map
map< int, const Node * > stage_id_to_node_map
Definition: FunctionDAG.h:612
Halide::Internal::Autoscheduler::FunctionDAG::Edge::consumer
FunctionDAG::Node::Stage * consumer
Definition: FunctionDAG.h:545
Halide::Internal::Autoscheduler::FunctionDAG::Edge::expand_footprint
void expand_footprint(const Span *consumer_loop, Span *producer_required) const
Halide::Internal::VariadicVisitor
A visitor/mutator capable of passing arbitrary arguments to the visit methods using CRTP and returnin...
Definition: IRVisitor.h:159
Halide::Internal::Variable
A named variable.
Definition: IR.h:741
Halide::Internal::Autoscheduler::BoundContents::data
Span * data() const
Definition: FunctionDAG.h:306
Halide::Internal::Autoscheduler::BoundContents::region_computed
const Span & region_computed(int i) const
Definition: FunctionDAG.h:327
Halide::Internal::Autoscheduler::FunctionDAG::Node::estimated_region_required
vector< Span > estimated_region_required
Definition: FunctionDAG.h:395
Halide::Internal::Autoscheduler::OptionalRational::operator==
bool operator==(const OptionalRational &other) const
Definition: FunctionDAG.h:126
Halide::Internal::Min
The lesser of two values.
Definition: IR.h:95
Halide::Internal::Autoscheduler::FunctionDAG::Node::max_id
int max_id
Definition: FunctionDAG.h:497
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::BoundInfo
BoundInfo(const Expr &e, const Node::Stage &consumer, bool dependent)
Halide::Internal::Autoscheduler::BoundContents::Layout::~Layout
~Layout()
Halide::Internal::Mod
The remainder of a / b.
Definition: IR.h:86
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::equals_region_computed
bool equals_region_computed
Definition: FunctionDAG.h:432
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::c_max
int64_t c_max
Definition: FunctionDAG.h:437
Halide::Internal::Autoscheduler::FunctionDAG::Edge::add_load_jacobian
void add_load_jacobian(LoadJacobian j1)
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::constant
int64_t constant
Definition: FunctionDAG.h:534
Halide::Internal::Autoscheduler::Span::constant_extent
bool constant_extent() const
Definition: FunctionDAG.h:266
Halide::Internal::Autoscheduler::FunctionDAG::Edge::bounds
vector< pair< BoundInfo, BoundInfo > > bounds
Definition: FunctionDAG.h:542
Halide::Internal::Function
A reference-counted handle to Halide's internal representation of a function.
Definition: Function.h:39
Halide::Internal::Autoscheduler::OptionalRational::operator*
OptionalRational operator*(const OptionalRational &other) const
Definition: FunctionDAG.h:72
Halide::Internal::Autoscheduler::OptionalRational::OptionalRational
OptionalRational(int64_t n, int64_t d)
Definition: FunctionDAG.h:41
Halide::Internal::Call
A function call.
Definition: IR.h:482
Halide::Internal::Autoscheduler::LoadJacobian
Definition: FunctionDAG.h:127
Halide::Internal::lcm
int64_t lcm(int64_t, int64_t)
The least common multiple of two integers.
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::loop_nest_all_common_cases
bool loop_nest_all_common_cases
Definition: FunctionDAG.h:458
Halide::Internal::Autoscheduler::Span::Span
Span(int64_t a, int64_t b, bool c)
Definition: FunctionDAG.h:285
Halide::Internal::Autoscheduler::FunctionDAG::Node::bounds_memory_layout
std::unique_ptr< BoundContents::Layout > bounds_memory_layout
Definition: FunctionDAG.h:519
Halide::Internal::Autoscheduler::ExprBranching::visit
int visit(const Reinterpret *op)
memcpy
void * memcpy(void *s1, const void *s2, size_t n)
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::incoming_edges
vector< Edge * > incoming_edges
Definition: FunctionDAG.h:477
Halide::Internal::Reinterpret
Reinterpret value as another type, without affecting any of the bits (on little-endian systems).
Definition: IR.h:39
Halide::Internal::Autoscheduler::LoadJacobian::is_constant
bool is_constant() const
Definition: FunctionDAG.h:165
Halide::Internal::Autoscheduler::FunctionDAG::Node::dimensions
int dimensions
Definition: FunctionDAG.h:502
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_boundary_condition
bool is_boundary_condition
Definition: FunctionDAG.h:517
Halide::Internal::Autoscheduler::BoundContents::ref_count
RefCount ref_count
Definition: FunctionDAG.h:276
PerfectHashMap
Definition: PerfectHashMap.h:38
Halide::Internal::Select
A ternary operator.
Definition: IR.h:196
Halide::Internal::Autoscheduler::OptionalRational::operator<
bool operator<(int x) const
Definition: FunctionDAG.h:88
Halide::Internal::Autoscheduler::OptionalRational::exists
bool exists
Definition: FunctionDAG.h:36
Halide::Internal::Autoscheduler::BoundContents::Layout::computed_offset
int computed_offset
Definition: FunctionDAG.h:342
Halide::Internal::Autoscheduler::OptionalRational
Definition: FunctionDAG.h:35
Halide::Internal::RefCount
A class representing a reference count to be used with IntrusivePtr.
Definition: IntrusivePtr.h:19
Halide::Internal::Autoscheduler::FunctionDAG::Node::func
Function func
Definition: FunctionDAG.h:384
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:257
Halide::Internal::Autoscheduler::FunctionDAG::Node::region_computed
vector< RegionComputedInfo > region_computed
Definition: FunctionDAG.h:413
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::c_max
int64_t c_max
Definition: FunctionDAG.h:411
Halide::Internal::Autoscheduler::BoundContents::region_required
const Span & region_required(int i) const
Definition: FunctionDAG.h:323
Halide::Internal::Autoscheduler::FunctionDAG::Edge::calls
int calls
Definition: FunctionDAG.h:549
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::var
string var
Definition: FunctionDAG.h:422
Halide::Internal::Autoscheduler::FunctionDAG::Edge::load_jacobians
vector< LoadJacobian > load_jacobians
Definition: FunctionDAG.h:553
Halide::Internal::Autoscheduler::ExprBranching::visit_nary
int visit_nary(const std::vector< Expr > &exprs)
Halide::Internal::GT
Is the first expression greater than the second.
Definition: IR.h:149
Halide::Internal::Autoscheduler::FunctionDAG::Node::region_required
vector< SymbolicInterval > region_required
Definition: FunctionDAG.h:391
Halide::Internal::Shuffle
Construct a new vector by taking elements from another sequence of vectors.
Definition: IR.h:819
Halide::Internal::Autoscheduler::BoundContents::loops
Span & loops(int i, int j)
Definition: FunctionDAG.h:319
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::c_min
int64_t c_min
Definition: FunctionDAG.h:437
Halide::Internal::Autoscheduler::FunctionDAG::Node::required_to_computed
void required_to_computed(const Span *required, Span *computed) const
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::equals_required
bool equals_required
Definition: FunctionDAG.h:410
Halide::Internal::Autoscheduler::Span::set_extent
void set_extent(int64_t e)
Definition: FunctionDAG.h:276
Halide::Internal::Autoscheduler::FunctionDAG::Node
Definition: FunctionDAG.h:379
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_pointwise
bool is_pointwise
Definition: FunctionDAG.h:514
Halide::Internal::Autoscheduler::BoundContents::Layout::loop_offset
std::vector< int > loop_offset
Definition: FunctionDAG.h:345
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::id
int id
Definition: FunctionDAG.h:475
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::vector_size
int vector_size
Definition: FunctionDAG.h:463
Halide::Internal::Autoscheduler::ExprBranching::visit_binary
int visit_binary(const Expr &a, const Expr &b)
Halide::Internal::UIntImm
Unsigned integer constants.
Definition: Expr.h:226
Halide::max
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:587
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::name
string name
Definition: FunctionDAG.h:472
Halide::Stage
A single definition of a Func.
Definition: Func.h:70
Halide::Internal::Autoscheduler::LoadJacobian::merge
bool merge(const LoadJacobian &other)
Definition: FunctionDAG.h:196
Halide::Internal::Autoscheduler::OptionalRational::operator==
bool operator==(int x) const
Definition: FunctionDAG.h:122
Halide::Internal::Autoscheduler::OptionalRational::denominator
int64_t denominator
Definition: FunctionDAG.h:37
Halide::Internal::Sub
The difference of two expressions.
Definition: IR.h:57
Halide::Internal::Autoscheduler::Span::union_with
void union_with(const Span &other)
Definition: FunctionDAG.h:270
Halide::Target
A struct representing a target machine and os to generate code for.
Definition: Target.h:19
Halide::Internal::Autoscheduler::OptionalRational::exists
bool exists() const
Definition: FunctionDAG.h:36
Halide::Internal::Autoscheduler::OptionalRational::OptionalRational
OptionalRational()=default
Halide::Internal::Autoscheduler::FunctionDAG::Edge::all_load_jacobian_coeffs_exist
bool all_load_jacobian_coeffs_exist() const
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::downstream_of
bool downstream_of(const Node &n) const
Definition: FunctionDAG.h:506
Halide::Internal::And
Logical and - are both expressions true.
Definition: IR.h:167
Halide::Internal::Autoscheduler::BoundContents::loops
const Span & loops(int i, int j) const
Definition: FunctionDAG.h:331
Halide::Internal::Autoscheduler::OptionalRational::operator*
OptionalRational operator*(int64_t factor) const
Definition: FunctionDAG.h:64
Halide::Internal::Autoscheduler::FunctionDAG::Node::id
int id
Definition: FunctionDAG.h:497
Halide::Internal::Autoscheduler::BoundContents::Layout::release
void release(const BoundContents *b) const
Halide::Internal::StringImm
String constants.
Definition: Expr.h:244
Halide::Internal::Not
Logical not - true if the expression false.
Definition: IR.h:185
Halide::Internal::Autoscheduler::ExprBranching
Definition: FunctionDAG.h:636
Halide::Internal::LT
Is the first expression less than the second.
Definition: IR.h:131
Halide::Internal::Autoscheduler::LoadJacobian::dump
void dump(std::ostream &os, const char *prefix) const
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_output
bool is_output
Definition: FunctionDAG.h:511
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::get_loop_index_from_var
int get_loop_index_from_var(const std::string &var) const
Definition: FunctionDAG.h:514
Halide::Internal::Mul
The product of two expressions.
Definition: IR.h:66
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::region_computed_dim
int region_computed_dim
Definition: FunctionDAG.h:433
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::in
Interval in
Definition: FunctionDAG.h:406
Halide::Internal::Autoscheduler::FunctionDAG::Edge::all_bounds_affine
bool all_bounds_affine
Definition: FunctionDAG.h:551