Loading...
Searching...
No Matches
FunctionDAG.h
Go to the documentation of this file.
/** This file defines the class FunctionDAG, which is our
* representation of a Halide pipeline, and contains methods to using
* Halide's bounds tools to query properties of it. */
#ifndef FUNCTION_DAG_H
#define FUNCTION_DAG_H
#include <algorithm>
#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "Featurization.h"
#include "HalidePlugin.h"
namespace Halide {
namespace Internal {
namespace Autoscheduler {
using std::map;
using std::pair;
using std::string;
using std::unique_ptr;
using std::vector;
struct Adams2019Params;
// First we have various utility classes.
// An optional rational type used when analyzing memory dependencies.
struct OptionalRational {
bool exists = false;
int64_t numerator = 0, denominator = 0;
OptionalRational() = default;
OptionalRational(bool e, int64_t n, int64_t d)
: exists(e), numerator(n), denominator(d) {
}
void operator+=(const OptionalRational &other) {
if (!exists || !other.exists) {
exists = false;
return;
}
if (denominator == other.denominator) {
numerator += other.numerator;
return;
}
int64_t l = lcm(denominator, other.denominator);
numerator *= l / denominator;
denominator = l;
numerator += other.numerator * (l / other.denominator);
int64_t g = gcd(numerator, denominator);
numerator /= g;
denominator /= g;
}
OptionalRational operator*(const OptionalRational &other) const {
if ((*this) == 0) {
return *this;
}
if (other == 0) {
return other;
}
int64_t num = numerator * other.numerator;
int64_t den = denominator * other.denominator;
bool e = exists && other.exists;
return OptionalRational{e, num, den};
}
// Because this type is optional (exists may be false), we don't
// have a total ordering. These methods all return false when the
// operators are not comparable, so a < b is not the same as !(a
// >= b).
bool operator<(int x) const {
if (!exists) {
return false;
}
if (denominator > 0) {
return numerator < x * denominator;
} else {
return numerator > x * denominator;
}
}
bool operator<=(int x) const {
if (!exists) {
return false;
}
if (denominator > 0) {
return numerator <= x * denominator;
} else {
return numerator >= x * denominator;
}
}
bool operator>(int x) const {
if (!exists) {
return false;
}
return !((*this) <= x);
}
bool operator>=(int x) const {
if (!exists) {
return false;
}
return !((*this) < x);
}
bool operator==(int x) const {
return exists && (numerator == (x * denominator));
}
bool operator==(const OptionalRational &other) const {
return (exists == other.exists) && (numerator * other.denominator == denominator * other.numerator);
}
};
// A LoadJacobian records the derivative of the coordinate accessed in
// some producer w.r.t the loops of the consumer.
class LoadJacobian {
vector<vector<OptionalRational>> coeffs;
int64_t c;
public:
explicit LoadJacobian(vector<vector<OptionalRational>> &&matrix, int64_t c = 1)
: coeffs(matrix), c(c) {
}
size_t producer_storage_dims() const {
return coeffs.size();
}
size_t consumer_loop_dims() const {
if (coeffs.empty() || coeffs[0].empty()) {
// The producer is scalar, and we don't know how
// many consumer loops there are.
return 0;
}
return coeffs[0].size();
}
OptionalRational operator()(int producer_storage_dim, int consumer_loop_dim) const {
if (coeffs.empty()) {
// The producer is scalar, so all strides are zero.
return {true, 0, 1};
}
internal_assert(producer_storage_dim < (int)coeffs.size());
const auto &p = coeffs[producer_storage_dim];
if (p.empty()) {
// The consumer is scalar, so all strides are zero.
return {true, 0, 1};
}
internal_assert(consumer_loop_dim < (int)p.size());
return p[consumer_loop_dim];
}
// To avoid redundantly re-recording copies of the same
// load Jacobian, we keep a count of how many times a
// load with this Jacobian occurs.
int64_t count() const {
return c;
}
// Try to merge another LoadJacobian into this one, increasing the
// count if the coefficients match.
bool merge(const LoadJacobian &other) {
if (other.coeffs.size() != coeffs.size()) {
return false;
}
for (size_t i = 0; i < coeffs.size(); i++) {
if (other.coeffs[i].size() != coeffs[i].size()) {
return false;
}
for (size_t j = 0; j < coeffs[i].size(); j++) {
if (!(other.coeffs[i][j] == coeffs[i][j])) {
return false;
}
}
}
c += other.count();
return true;
}
// Multiply Jacobians, used to look at memory dependencies through
// inlined functions.
LoadJacobian operator*(const LoadJacobian &other) const {
vector<vector<OptionalRational>> matrix;
internal_assert(consumer_loop_dims() == 0 || (consumer_loop_dims() == other.producer_storage_dims()));
matrix.resize(producer_storage_dims());
for (size_t i = 0; i < producer_storage_dims(); i++) {
matrix[i].resize(other.consumer_loop_dims());
for (size_t j = 0; j < other.consumer_loop_dims(); j++) {
matrix[i][j] = OptionalRational{true, 0, 1};
for (size_t k = 0; k < consumer_loop_dims(); k++) {
matrix[i][j] += (*this)(i, k) * other(k, j);
}
}
}
LoadJacobian result(std::move(matrix), count() * other.count());
return result;
}
void dump(std::ostream &os, const char *prefix) const;
};
// Classes to represent a concrete set of bounds for a Func. A Span is
// single-dimensional, and a Bound is a multi-dimensional box. For
// each dimension we track the estimated size, and also whether or not
// the size is known to be constant at compile-time. For each Func we
// track three different types of bounds:
// 1) The region required by consumers of the Func, which determines
// 2) The region actually computed, which in turn determines
// 3) The min and max of all loops in the loop next.
// 3 in turn determines the region required of the inputs to a Func,
// which determines their region computed, and hence their loop nest,
// and so on back up the Function DAG from outputs back to inputs.
class Span {
int64_t min_, max_;
bool constant_extent_;
public:
int64_t min() const {
return min_;
}
int64_t max() const {
return max_;
}
int64_t extent() const {
return max_ - min_ + 1;
}
bool constant_extent() const {
return constant_extent_;
}
void union_with(const Span &other) {
min_ = std::min(min_, other.min());
max_ = std::max(max_, other.max());
constant_extent_ = constant_extent_ && other.constant_extent();
}
void set_extent(int64_t e) {
max_ = min_ + e - 1;
}
void translate(int64_t x) {
min_ += x;
max_ += x;
}
Span(int64_t a, int64_t b, bool c)
: min_(a), max_(b), constant_extent_(c) {
}
Span() = default;
Span(const Span &other) = default;
static Span empty_span() {
return Span(INT64_MAX, INT64_MIN, true);
}
};
// Bounds objects are created and destroyed very frequently while
// exploring scheduling options, so we have a custom allocator and
// memory pool. Much like IR nodes, we treat them as immutable once
// created and wrapped in a Bound object so that they can be shared
// safely across scheduling alternatives.
struct BoundContents {
mutable RefCount ref_count;
class Layout;
const Layout *layout = nullptr;
Span *data() const {
// This struct is a header
return (Span *)(const_cast<BoundContents *>(this) + 1);
}
Span &region_required(int i) {
return data()[i];
}
Span &region_computed(int i) {
return data()[i + layout->computed_offset];
}
Span &loops(int i, int j) {
return data()[j + layout->loop_offset[i]];
}
const Span &region_required(int i) const {
return data()[i];
}
const Span &region_computed(int i) const {
return data()[i + layout->computed_offset];
}
const Span &loops(int i, int j) const {
return data()[j + layout->loop_offset[i]];
}
BoundContents *make_copy() const {
auto *b = layout->make();
size_t bytes = sizeof(data()[0]) * layout->total_size;
memcpy(b->data(), data(), bytes);
return b;
}
void validate() const;
// We're frequently going to need to make these concrete bounds
// arrays. It makes things more efficient if we figure out the
// memory layout of those data structures once ahead of time, and
// make each individual instance just use that. Note that this is
// not thread-safe.
class Layout {
// A memory pool of free BoundContent objects with this layout
mutable std::vector<BoundContents *> pool;
// All the blocks of memory allocated
mutable std::vector<void *> blocks;
mutable size_t num_live = 0;
void allocate_some_more() const;
public:
// number of Span to allocate
int total_size;
// region_required has size func->dimensions() and comes first in the memory layout
// region_computed comes next at the following index
int computed_offset;
// the loop for each stage starts at the following index
std::vector<int> loop_offset;
Layout() = default;
~Layout();
Layout(const Layout &) = delete;
void operator=(const Layout &) = delete;
Layout(Layout &&) = delete;
void operator=(Layout &&) = delete;
// Make a BoundContents object with this layout
BoundContents *make() const;
// Release a BoundContents object with this layout back to the pool
void release(const BoundContents *b) const;
};
};
using Bound = IntrusivePtr<const BoundContents>;
// A representation of the function DAG. The nodes and edges are both
// in reverse realization order, so if you want to walk backwards up
// the DAG, just iterate the nodes or edges in-order.
struct FunctionDAG {
// An edge is a producer-consumer relationship
struct Edge;
struct SymbolicInterval {
Halide::Var min;
Halide::Var max;
};
// A Node represents a single Func
struct Node {
// A pointer back to the owning DAG
FunctionDAG *dag;
// The Halide Func this represents
Function func;
// The number of bytes per point stored.
double bytes_per_point;
// The min/max variables used to denote a symbolic region of
// this Func. Used in the cost above, and in the Edges below.
vector<SymbolicInterval> region_required;
// A concrete region required from a bounds estimate. Only
// defined for outputs.
vector<Span> estimated_region_required;
// The region computed of a Func, in terms of the region
// required. For simple Funcs this is identical to the
// region_required. However, in some Funcs computing one
// output requires computing other outputs too. You can't
// really ask for a single output pixel from something blurred
// with an IIR without computing the others, for example.
struct RegionComputedInfo {
// The min and max in their full symbolic glory. We use
// these in the general case.
Interval in;
bool depends_on_estimate = false;
// Analysis used to accelerate common cases
bool equals_required = false, equals_union_of_required_with_constants = false;
int64_t c_min = 0, c_max = 0;
};
vector<RegionComputedInfo> region_computed;
bool region_computed_all_common_cases = false;
// Expand a region required into a region computed, using the
// symbolic intervals above.
void required_to_computed(const Span *required, Span *computed) const;
// Metadata about one symbolic loop in a Func's default loop nest.
struct Loop {
string var;
bool pure, rvar;
Expr min, max;
// Which pure dimension does this loop correspond to? Invalid if it's an rvar
int pure_dim;
// Precomputed metadata to accelerate common cases:
// If true, the loop bounds are just the region computed in the given dimension
bool equals_region_computed = false;
int region_computed_dim = 0;
// If true, the loop bounds are a constant with the given min and max
bool bounds_are_constant = false;
int64_t c_min = 0, c_max = 0;
// A persistent fragment of source for getting this Var
// from its owner Func. Used for printing source code
// equivalent to a computed schedule.
string accessor;
};
// Get the loop nest shape as a function of the region computed
void loop_nest_for_region(int stage_idx, const Span *computed, Span *loop) const;
// One stage of a Func
struct Stage {
// The owning Node
Node *node;
// Which stage of the Func is this. 0 = pure.
int index;
// The loop nest that computes this stage, from innermost out.
vector<Loop> loop;
bool loop_nest_all_common_cases = false;
// The vectorization width that will be used for
// compute. Corresponds to the natural width for the
// narrowest type used.
int vector_size;
// The featurization of the compute done
PipelineFeatures features;
// The actual Halide front-end stage object
Halide::Stage stage;
// The name for scheduling (e.g. "foo.update(3)")
string name;
// Ids for perfect hashing on stages.
int id, max_id;
vector<Edge *> incoming_edges;
vector<bool> dependencies;
bool downstream_of(const Node &n) const {
return dependencies[n.id];
};
explicit Stage(Halide::Stage s)
: stage(std::move(s)) {
}
};
vector<Stage> stages;
vector<Edge *> outgoing_edges;
// Max vector size across the stages
int vector_size;
// A unique ID for this node, allocated consecutively starting
// at zero for each pipeline.
int id, max_id;
// Just func->dimensions(), but we ask for it so many times
// that's it's worth avoiding the function call into
// libHalide.
int dimensions;
// Is a single pointwise call to another Func
bool is_wrapper;
// We represent the input buffers as node, though we do not attempt to schedule them.
bool is_input;
// Is one of the pipeline outputs
bool is_output;
// Only uses pointwise calls
bool is_pointwise;
// Only uses pointwise calls + clamping on all indices
bool is_boundary_condition;
std::unique_ptr<BoundContents::Layout> bounds_memory_layout;
BoundContents *make_bound() const {
return bounds_memory_layout->make();
}
};
// A representation of a producer-consumer relationship
struct Edge {
struct BoundInfo {
// The symbolic expression for the bound in this dimension
Expr expr;
// Fields below are the results of additional analysis
// used to evaluate this bound more quickly.
int64_t coeff, constant;
int64_t consumer_dim;
bool affine, uses_max, depends_on_estimate;
BoundInfo(const Expr &e, const Node::Stage &consumer, bool dependent);
};
// Memory footprint on producer required by consumer.
vector<pair<BoundInfo, BoundInfo>> bounds;
FunctionDAG::Node *producer;
FunctionDAG::Node::Stage *consumer;
// The number of calls the consumer makes to the producer, per
// point in the loop nest of the consumer.
int calls;
bool all_bounds_affine;
vector<LoadJacobian> load_jacobians;
void add_load_jacobian(LoadJacobian j1);
// Given a loop nest of the consumer stage, expand a region
// required of the producer to be large enough to include all
// points required.
void expand_footprint(const Span *consumer_loop, Span *producer_required) const;
};
vector<Node> nodes;
vector<Edge> edges;
// Create the function DAG, and do all the dependency and cost
// analysis. This is done once up-front before the tree search.
FunctionDAG(const vector<Function> &outputs, const Target &target);
void dump(std::ostream &os) const;
private:
// Compute the featurization for the entire DAG
void featurize();
public:
// This class uses a lot of internal pointers, so we'll make it uncopyable/unmovable.
FunctionDAG(const FunctionDAG &other) = delete;
FunctionDAG &operator=(const FunctionDAG &other) = delete;
FunctionDAG(FunctionDAG &&other) = delete;
FunctionDAG &operator=(FunctionDAG &&other) = delete;
};
} // namespace Autoscheduler
} // namespace Internal
} // namespace Halide
#endif // FUNCTION_DAG_H
internal_assert
#define internal_assert(c)
Definition Error.h:218
HalidePlugin.h
Featurization.h
Halide::Internal::Autoscheduler::BoundContents::Layout
Definition FunctionDAG.h:323
Halide::Internal::Autoscheduler::BoundContents::Layout::~Layout
~Layout()
Halide::Internal::Autoscheduler::BoundContents::Layout::release
void release(const BoundContents *b) const
Halide::Internal::Autoscheduler::BoundContents::Layout::Layout
Layout(Layout &&)=delete
Halide::Internal::Autoscheduler::BoundContents::Layout::operator=
void operator=(Layout &&)=delete
Halide::Internal::Autoscheduler::BoundContents::Layout::computed_offset
int computed_offset
Definition FunctionDAG.h:341
Halide::Internal::Autoscheduler::BoundContents::Layout::Layout
Layout()=default
Halide::Internal::Autoscheduler::BoundContents::Layout::Layout
Layout(const Layout &)=delete
Halide::Internal::Autoscheduler::BoundContents::Layout::loop_offset
std::vector< int > loop_offset
Definition FunctionDAG.h:344
Halide::Internal::Autoscheduler::BoundContents::Layout::make
BoundContents * make() const
Halide::Internal::Autoscheduler::BoundContents::Layout::total_size
int total_size
Definition FunctionDAG.h:336
Halide::Internal::Autoscheduler::BoundContents::Layout::operator=
void operator=(const Layout &)=delete
Halide::Internal::Autoscheduler::LoadJacobian
Definition FunctionDAG.h:126
Halide::Internal::Autoscheduler::LoadJacobian::operator()
OptionalRational operator()(int producer_storage_dim, int consumer_loop_dim) const
Definition FunctionDAG.h:148
Halide::Internal::Autoscheduler::LoadJacobian::operator*
LoadJacobian operator*(const LoadJacobian &other) const
Definition FunctionDAG.h:192
Halide::Internal::Autoscheduler::LoadJacobian::consumer_loop_dims
size_t consumer_loop_dims() const
Definition FunctionDAG.h:139
Halide::Internal::Autoscheduler::LoadJacobian::count
int64_t count() const
Definition FunctionDAG.h:166
Halide::Internal::Autoscheduler::LoadJacobian::merge
bool merge(const LoadJacobian &other)
Definition FunctionDAG.h:172
Halide::Internal::Autoscheduler::LoadJacobian::LoadJacobian
LoadJacobian(vector< vector< OptionalRational > > &&matrix, int64_t c=1)
Definition FunctionDAG.h:131
Halide::Internal::Autoscheduler::LoadJacobian::producer_storage_dims
size_t producer_storage_dims() const
Definition FunctionDAG.h:135
Halide::Internal::Autoscheduler::LoadJacobian::dump
void dump(std::ostream &os, const char *prefix) const
Halide::Internal::Autoscheduler::Span
Definition FunctionDAG.h:226
Halide::Internal::Autoscheduler::Span::max
int64_t max() const
Definition FunctionDAG.h:234
Halide::Internal::Autoscheduler::Span::constant_extent
bool constant_extent() const
Definition FunctionDAG.h:240
Halide::Internal::Autoscheduler::Span::Span
Span()=default
Halide::Internal::Autoscheduler::Span::set_extent
void set_extent(int64_t e)
Definition FunctionDAG.h:250
Halide::Internal::Autoscheduler::Span::extent
int64_t extent() const
Definition FunctionDAG.h:237
Halide::Internal::Autoscheduler::Span::Span
Span(int64_t a, int64_t b, bool c)
Definition FunctionDAG.h:259
Halide::Internal::Autoscheduler::Span::translate
void translate(int64_t x)
Definition FunctionDAG.h:254
Halide::Internal::Autoscheduler::Span::min
int64_t min() const
Definition FunctionDAG.h:231
Halide::Internal::Autoscheduler::Span::empty_span
static Span empty_span()
Definition FunctionDAG.h:264
Halide::Internal::Autoscheduler::Span::Span
Span(const Span &other)=default
Halide::Internal::Autoscheduler::Span::union_with
void union_with(const Span &other)
Definition FunctionDAG.h:244
Halide::Internal::Function
A reference-counted handle to Halide's internal representation of a function.
Definition Function.h:39
Halide::Internal::RefCount
A class representing a reference count to be used with IntrusivePtr.
Definition IntrusivePtr.h:19
Halide::Stage
A single definition of a Func.
Definition Func.h:70
Halide::Var
A Halide variable, to be used when defining functions.
Definition Var.h:19
Halide::Internal::Autoscheduler
Definition AutoSchedule.h:10
Halide::Internal::Autoscheduler::Bound
IntrusivePtr< const BoundContents > Bound
Definition FunctionDAG.h:362
Halide::Internal
Definition AbstractGenerator.h:24
Halide::Internal::gcd
int64_t gcd(int64_t, int64_t)
The greatest common divisor of two integers.
Halide::Internal::lcm
int64_t lcm(int64_t, int64_t)
The least common multiple of two integers.
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition AbstractGenerator.h:19
int64_t
signed __INT64_TYPE__ int64_t
Definition runtime_internal.h:22
memcpy
void * memcpy(void *s1, const void *s2, size_t n)
Halide::Expr
A fragment of Halide syntax.
Definition Expr.h:258
Halide::Internal::Autoscheduler::Adams2019Params
Definition CostModel.h:19
Halide::Internal::Autoscheduler::BoundContents
Definition FunctionDAG.h:274
Halide::Internal::Autoscheduler::BoundContents::region_computed
Span & region_computed(int i)
Definition FunctionDAG.h:289
Halide::Internal::Autoscheduler::BoundContents::region_required
Span & region_required(int i)
Definition FunctionDAG.h:285
Halide::Internal::Autoscheduler::BoundContents::data
Span * data() const
Definition FunctionDAG.h:280
Halide::Internal::Autoscheduler::BoundContents::loops
Span & loops(int i, int j)
Definition FunctionDAG.h:293
Halide::Internal::Autoscheduler::BoundContents::validate
void validate() const
Halide::Internal::Autoscheduler::BoundContents::make_copy
BoundContents * make_copy() const
Definition FunctionDAG.h:309
Halide::Internal::Autoscheduler::BoundContents::layout
const Layout * layout
Definition FunctionDAG.h:278
Halide::Internal::Autoscheduler::BoundContents::region_required
const Span & region_required(int i) const
Definition FunctionDAG.h:297
Halide::Internal::Autoscheduler::BoundContents::region_computed
const Span & region_computed(int i) const
Definition FunctionDAG.h:301
Halide::Internal::Autoscheduler::BoundContents::ref_count
RefCount ref_count
Definition FunctionDAG.h:275
Halide::Internal::Autoscheduler::BoundContents::loops
const Span & loops(int i, int j) const
Definition FunctionDAG.h:305
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::depends_on_estimate
bool depends_on_estimate
Definition FunctionDAG.h:535
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::affine
bool affine
Definition FunctionDAG.h:535
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::uses_max
bool uses_max
Definition FunctionDAG.h:535
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::consumer_dim
int64_t consumer_dim
Definition FunctionDAG.h:534
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::coeff
int64_t coeff
Definition FunctionDAG.h:533
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::constant
int64_t constant
Definition FunctionDAG.h:533
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::expr
Expr expr
Definition FunctionDAG.h:529
Halide::Internal::Autoscheduler::FunctionDAG::Edge::BoundInfo::BoundInfo
BoundInfo(const Expr &e, const Node::Stage &consumer, bool dependent)
Halide::Internal::Autoscheduler::FunctionDAG::Edge
Definition FunctionDAG.h:526
Halide::Internal::Autoscheduler::FunctionDAG::Edge::producer
FunctionDAG::Node * producer
Definition FunctionDAG.h:543
Halide::Internal::Autoscheduler::FunctionDAG::Edge::load_jacobians
vector< LoadJacobian > load_jacobians
Definition FunctionDAG.h:552
Halide::Internal::Autoscheduler::FunctionDAG::Edge::calls
int calls
Definition FunctionDAG.h:548
Halide::Internal::Autoscheduler::FunctionDAG::Edge::expand_footprint
void expand_footprint(const Span *consumer_loop, Span *producer_required) const
Halide::Internal::Autoscheduler::FunctionDAG::Edge::add_load_jacobian
void add_load_jacobian(LoadJacobian j1)
Halide::Internal::Autoscheduler::FunctionDAG::Edge::consumer
FunctionDAG::Node::Stage * consumer
Definition FunctionDAG.h:544
Halide::Internal::Autoscheduler::FunctionDAG::Edge::all_bounds_affine
bool all_bounds_affine
Definition FunctionDAG.h:550
Halide::Internal::Autoscheduler::FunctionDAG::Edge::bounds
vector< pair< BoundInfo, BoundInfo > > bounds
Definition FunctionDAG.h:541
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop
Definition FunctionDAG.h:420
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::min
Expr min
Definition FunctionDAG.h:423
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::pure_dim
int pure_dim
Definition FunctionDAG.h:426
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::c_max
int64_t c_max
Definition FunctionDAG.h:436
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::region_computed_dim
int region_computed_dim
Definition FunctionDAG.h:432
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::rvar
bool rvar
Definition FunctionDAG.h:422
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::pure
bool pure
Definition FunctionDAG.h:422
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::var
string var
Definition FunctionDAG.h:421
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::max
Expr max
Definition FunctionDAG.h:423
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::accessor
string accessor
Definition FunctionDAG.h:441
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::equals_region_computed
bool equals_region_computed
Definition FunctionDAG.h:431
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::c_min
int64_t c_min
Definition FunctionDAG.h:436
Halide::Internal::Autoscheduler::FunctionDAG::Node::Loop::bounds_are_constant
bool bounds_are_constant
Definition FunctionDAG.h:435
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo
Definition FunctionDAG.h:402
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::in
Interval in
Definition FunctionDAG.h:405
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::c_max
int64_t c_max
Definition FunctionDAG.h:410
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::depends_on_estimate
bool depends_on_estimate
Definition FunctionDAG.h:406
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::c_min
int64_t c_min
Definition FunctionDAG.h:410
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::equals_union_of_required_with_constants
bool equals_union_of_required_with_constants
Definition FunctionDAG.h:409
Halide::Internal::Autoscheduler::FunctionDAG::Node::RegionComputedInfo::equals_required
bool equals_required
Definition FunctionDAG.h:409
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage
Definition FunctionDAG.h:448
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::index
int index
Definition FunctionDAG.h:453
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::Stage
Stage(Halide::Stage s)
Definition FunctionDAG.h:483
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::features
PipelineFeatures features
Definition FunctionDAG.h:465
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::id
int id
Definition FunctionDAG.h:474
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::loop_nest_all_common_cases
bool loop_nest_all_common_cases
Definition FunctionDAG.h:457
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::loop
vector< Loop > loop
Definition FunctionDAG.h:456
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::max_id
int max_id
Definition FunctionDAG.h:474
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::downstream_of
bool downstream_of(const Node &n) const
Definition FunctionDAG.h:479
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::vector_size
int vector_size
Definition FunctionDAG.h:462
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::node
Node * node
Definition FunctionDAG.h:450
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::name
string name
Definition FunctionDAG.h:471
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::dependencies
vector< bool > dependencies
Definition FunctionDAG.h:478
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::stage
Halide::Stage stage
Definition FunctionDAG.h:468
Halide::Internal::Autoscheduler::FunctionDAG::Node::Stage::incoming_edges
vector< Edge * > incoming_edges
Definition FunctionDAG.h:476
Halide::Internal::Autoscheduler::FunctionDAG::Node
Definition FunctionDAG.h:378
Halide::Internal::Autoscheduler::FunctionDAG::Node::id
int id
Definition FunctionDAG.h:496
Halide::Internal::Autoscheduler::FunctionDAG::Node::outgoing_edges
vector< Edge * > outgoing_edges
Definition FunctionDAG.h:489
Halide::Internal::Autoscheduler::FunctionDAG::Node::make_bound
BoundContents * make_bound() const
Definition FunctionDAG.h:520
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_input
bool is_input
Definition FunctionDAG.h:507
Halide::Internal::Autoscheduler::FunctionDAG::Node::region_required
vector< SymbolicInterval > region_required
Definition FunctionDAG.h:390
Halide::Internal::Autoscheduler::FunctionDAG::Node::func
Function func
Definition FunctionDAG.h:383
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::dimensions
int dimensions
Definition FunctionDAG.h:501
Halide::Internal::Autoscheduler::FunctionDAG::Node::dag
FunctionDAG * dag
Definition FunctionDAG.h:380
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_boundary_condition
bool is_boundary_condition
Definition FunctionDAG.h:516
Halide::Internal::Autoscheduler::FunctionDAG::Node::region_computed
vector< RegionComputedInfo > region_computed
Definition FunctionDAG.h:412
Halide::Internal::Autoscheduler::FunctionDAG::Node::region_computed_all_common_cases
bool region_computed_all_common_cases
Definition FunctionDAG.h:413
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_wrapper
bool is_wrapper
Definition FunctionDAG.h:504
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_pointwise
bool is_pointwise
Definition FunctionDAG.h:513
Halide::Internal::Autoscheduler::FunctionDAG::Node::max_id
int max_id
Definition FunctionDAG.h:496
Halide::Internal::Autoscheduler::FunctionDAG::Node::estimated_region_required
vector< Span > estimated_region_required
Definition FunctionDAG.h:394
Halide::Internal::Autoscheduler::FunctionDAG::Node::stages
vector< Stage > stages
Definition FunctionDAG.h:487
Halide::Internal::Autoscheduler::FunctionDAG::Node::bytes_per_point
double bytes_per_point
Definition FunctionDAG.h:386
Halide::Internal::Autoscheduler::FunctionDAG::Node::vector_size
int vector_size
Definition FunctionDAG.h:492
Halide::Internal::Autoscheduler::FunctionDAG::Node::bounds_memory_layout
std::unique_ptr< BoundContents::Layout > bounds_memory_layout
Definition FunctionDAG.h:518
Halide::Internal::Autoscheduler::FunctionDAG::Node::is_output
bool is_output
Definition FunctionDAG.h:510
Halide::Internal::Autoscheduler::FunctionDAG::Node::required_to_computed
void required_to_computed(const Span *required, Span *computed) const
Halide::Internal::Autoscheduler::FunctionDAG::SymbolicInterval
Definition FunctionDAG.h:372
Halide::Internal::Autoscheduler::FunctionDAG::SymbolicInterval::max
Halide::Var max
Definition FunctionDAG.h:374
Halide::Internal::Autoscheduler::FunctionDAG::SymbolicInterval::min
Halide::Var min
Definition FunctionDAG.h:373
Halide::Internal::Autoscheduler::FunctionDAG::nodes
vector< Node > nodes
Definition FunctionDAG.h:562
Halide::Internal::Autoscheduler::FunctionDAG::dump
void dump(std::ostream &os) const
Halide::Internal::Autoscheduler::FunctionDAG::FunctionDAG
FunctionDAG(FunctionDAG &&other)=delete
Halide::Internal::Autoscheduler::FunctionDAG::FunctionDAG
FunctionDAG(const FunctionDAG &other)=delete
Halide::Internal::Autoscheduler::FunctionDAG::operator=
FunctionDAG & operator=(FunctionDAG &&other)=delete
Halide::Internal::Autoscheduler::FunctionDAG::operator=
FunctionDAG & operator=(const FunctionDAG &other)=delete
Halide::Internal::Autoscheduler::FunctionDAG::FunctionDAG
FunctionDAG(const vector< Function > &outputs, const Target &target)
Halide::Internal::Autoscheduler::FunctionDAG::edges
vector< Edge > edges
Definition FunctionDAG.h:563
Halide::Internal::Autoscheduler::OptionalRational
Definition FunctionDAG.h:34
Halide::Internal::Autoscheduler::OptionalRational::operator+=
void operator+=(const OptionalRational &other)
Definition FunctionDAG.h:43
Halide::Internal::Autoscheduler::OptionalRational::numerator
int64_t numerator
Definition FunctionDAG.h:36
Halide::Internal::Autoscheduler::OptionalRational::operator>=
bool operator>=(int x) const
Definition FunctionDAG.h:108
Halide::Internal::Autoscheduler::OptionalRational::OptionalRational
OptionalRational(bool e, int64_t n, int64_t d)
Definition FunctionDAG.h:39
Halide::Internal::Autoscheduler::OptionalRational::operator==
bool operator==(const OptionalRational &other) const
Definition FunctionDAG.h:119
Halide::Internal::Autoscheduler::OptionalRational::operator>
bool operator>(int x) const
Definition FunctionDAG.h:101
Halide::Internal::Autoscheduler::OptionalRational::OptionalRational
OptionalRational()=default
Halide::Internal::Autoscheduler::OptionalRational::denominator
int64_t denominator
Definition FunctionDAG.h:36
Halide::Internal::Autoscheduler::OptionalRational::operator*
OptionalRational operator*(const OptionalRational &other) const
Definition FunctionDAG.h:62
Halide::Internal::Autoscheduler::OptionalRational::operator==
bool operator==(int x) const
Definition FunctionDAG.h:115
Halide::Internal::Autoscheduler::OptionalRational::operator<
bool operator<(int x) const
Definition FunctionDAG.h:79
Halide::Internal::Autoscheduler::OptionalRational::operator<=
bool operator<=(int x) const
Definition FunctionDAG.h:90
Halide::Internal::Autoscheduler::OptionalRational::exists
bool exists
Definition FunctionDAG.h:35
Halide::Internal::Interval
A class to represent ranges of Exprs.
Definition Interval.h:14
Halide::Internal::IntrusivePtr
Intrusive shared pointers have a reference count (a RefCount object) stored in the class itself.
Definition IntrusivePtr.h:71
Halide::Internal::PipelineFeatures
Definition Featurization.h:13
Halide::Target
A struct representing a target machine and os to generate code for.
Definition Target.h:19