Halide 19.0.0
Halide compiler and libraries
Loading...
Searching...
No Matches
Bounds.h
Go to the documentation of this file.
1#ifndef HALIDE_BOUNDS_H
2#define HALIDE_BOUNDS_H
3
4/** \file
5 * Methods for computing the upper and lower bounds of an expression,
6 * and the regions of a function read or written by a statement.
7 */
8
9#include "Interval.h"
10#include "Scope.h"
11
12namespace Halide {
13namespace Internal {
14
15class Function;
16
17typedef std::map<std::pair<std::string, int>, Interval> FuncValueBounds;
18
20
21/** Given an expression in some variables, and a map from those
22 * variables to their bounds (in the form of (minimum possible value,
23 * maximum possible value)), compute two expressions that give the
24 * minimum possible value and the maximum possible value of this
25 * expression. Max or min may be undefined expressions if the value is
26 * not bounded above or below. If the expression is a vector, also
27 * takes the bounds across the vector lanes and returns a scalar
28 * result.
29 *
30 * This is for tasks such as deducing the region of a buffer
31 * loaded by a chunk of code.
32 */
34 const Scope<Interval> &scope,
35 const FuncValueBounds &func_bounds = empty_func_value_bounds(),
36 bool const_bound = false);
37
38/** Given a varying expression, try to find a constant that is either:
39 * An upper bound (always greater than or equal to the expression), or
40 * A lower bound (always less than or equal to the expression)
41 * If it fails, returns an undefined Expr. */
42enum class Direction { Upper,
43 Lower };
46
47/** Find bounds for a varying expression that are either constants or
48 * +/-inf. */
50
51/** Represents the bounds of a region of arbitrary dimension. Zero
52 * dimensions corresponds to a scalar region. */
53struct Box {
54 /** The conditions under which this region may be touched. */
56
57 /** The bounds if it is touched. */
58 std::vector<Interval> bounds;
59
60 Box() = default;
61 explicit Box(size_t sz)
62 : bounds(sz) {
63 }
64 explicit Box(const std::vector<Interval> &b)
65 : bounds(b) {
66 }
67
68 size_t size() const {
69 return bounds.size();
70 }
71 bool empty() const {
72 return bounds.empty();
73 }
74 Interval &operator[](size_t i) {
75 return bounds[i];
76 }
77 const Interval &operator[](size_t i) const {
78 return bounds[i];
79 }
80 void resize(size_t sz) {
81 bounds.resize(sz);
82 }
83 void push_back(const Interval &i) {
84 bounds.push_back(i);
85 }
86
87 /** Check if the used condition is defined and not trivially true. */
88 bool maybe_unused() const;
89
90 friend std::ostream &operator<<(std::ostream &stream, const Box &b);
91};
92
93/** Expand box a to encompass box b */
94void merge_boxes(Box &a, const Box &b);
95
96/** Test if box a could possibly overlap box b. */
97bool boxes_overlap(const Box &a, const Box &b);
98
99/** The union of two boxes */
100Box box_union(const Box &a, const Box &b);
101
102/** The intersection of two boxes */
103Box box_intersection(const Box &a, const Box &b);
104
105/** Test if box a provably contains box b */
106bool box_contains(const Box &a, const Box &b);
107
108/** Compute rectangular domains large enough to cover all the 'Call's to each
109 * function that occurs within a given statement or expression. This is useful
110 * for figuring out what regions of things to evaluate. Respects control flow
111 * (e.g. encodes if statement conditions), but assumes all encountered asserts
112 * pass. If it encounters an assert(false) in one if branch, assumes the
113 * opposite if branch runs unconditionally. */
114// @{
115std::map<std::string, Box> boxes_required(const Expr &e,
117 const FuncValueBounds &func_bounds = empty_func_value_bounds());
118std::map<std::string, Box> boxes_required(Stmt s,
120 const FuncValueBounds &func_bounds = empty_func_value_bounds());
121// @}
122
123/** Compute rectangular domains large enough to cover all the 'Provides's to
124 * each function that occurs within a given statement or expression. Handles
125 * asserts in the same way as boxes_required. */
126// @{
127std::map<std::string, Box> boxes_provided(const Expr &e,
129 const FuncValueBounds &func_bounds = empty_func_value_bounds());
130std::map<std::string, Box> boxes_provided(Stmt s,
132 const FuncValueBounds &func_bounds = empty_func_value_bounds());
133// @}
134
135/** Compute rectangular domains large enough to cover all the 'Call's and
136 * 'Provides's to each function that occurs within a given statement or
137 * expression. Handles asserts in the same way as boxes_required. */
138// @{
139std::map<std::string, Box> boxes_touched(const Expr &e,
141 const FuncValueBounds &func_bounds = empty_func_value_bounds());
142std::map<std::string, Box> boxes_touched(Stmt s,
144 const FuncValueBounds &func_bounds = empty_func_value_bounds());
145// @}
146
147/** Variants of the above that are only concerned with a single function. */
148// @{
149Box box_required(const Expr &e, const std::string &fn,
151 const FuncValueBounds &func_bounds = empty_func_value_bounds());
152Box box_required(Stmt s, const std::string &fn,
154 const FuncValueBounds &func_bounds = empty_func_value_bounds());
155
156Box box_provided(const Expr &e, const std::string &fn,
158 const FuncValueBounds &func_bounds = empty_func_value_bounds());
159Box box_provided(Stmt s, const std::string &fn,
161 const FuncValueBounds &func_bounds = empty_func_value_bounds());
162
163Box box_touched(const Expr &e, const std::string &fn,
165 const FuncValueBounds &func_bounds = empty_func_value_bounds());
166Box box_touched(Stmt s, const std::string &fn,
168 const FuncValueBounds &func_bounds = empty_func_value_bounds());
169// @}
170
171/** Compute the maximum and minimum possible value for each function
172 * in an environment. */
173FuncValueBounds compute_function_value_bounds(const std::vector<std::string> &order,
174 const std::map<std::string, Function> &env);
175
176/* Find an upper bound of bounds.max - bounds.min. */
178
180
181} // namespace Internal
182} // namespace Halide
183
184#endif
Defines the Interval class.
Defines the Scope class, which is used for keeping track of names in a scope while traversing IR.
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
Definition Scope.h:94
FuncValueBounds compute_function_value_bounds(const std::vector< std::string > &order, const std::map< std::string, Function > &env)
Compute the maximum and minimum possible value for each function in an environment.
Expr find_constant_bound(const Expr &e, Direction d, const Scope< Interval > &scope=Scope< Interval >::empty_scope())
Box box_required(const Expr &e, const std::string &fn, const Scope< Interval > &scope=Scope< Interval >::empty_scope(), const FuncValueBounds &func_bounds=empty_func_value_bounds())
Variants of the above that are only concerned with a single function.
const FuncValueBounds & empty_func_value_bounds()
std::map< std::string, Box > boxes_touched(const Expr &e, const Scope< Interval > &scope=Scope< Interval >::empty_scope(), const FuncValueBounds &func_bounds=empty_func_value_bounds())
Compute rectangular domains large enough to cover all the 'Call's and 'Provides's to each function th...
Direction
Given a varying expression, try to find a constant that is either: An upper bound (always greater tha...
Definition Bounds.h:42
std::map< std::string, Box > boxes_provided(const Expr &e, const Scope< Interval > &scope=Scope< Interval >::empty_scope(), const FuncValueBounds &func_bounds=empty_func_value_bounds())
Compute rectangular domains large enough to cover all the 'Provides's to each function that occurs wi...
Box box_intersection(const Box &a, const Box &b)
The intersection of two boxes.
bool box_contains(const Box &a, const Box &b)
Test if box a provably contains box b.
Interval bounds_of_expr_in_scope(const Expr &expr, const Scope< Interval > &scope, const FuncValueBounds &func_bounds=empty_func_value_bounds(), bool const_bound=false)
Given an expression in some variables, and a map from those variables to their bounds (in the form of...
Expr span_of_bounds(const Interval &bounds)
Interval find_constant_bounds(const Expr &e, const Scope< Interval > &scope)
Find bounds for a varying expression that are either constants or +/-inf.
Box box_touched(const Expr &e, const std::string &fn, const Scope< Interval > &scope=Scope< Interval >::empty_scope(), const FuncValueBounds &func_bounds=empty_func_value_bounds())
std::map< std::pair< std::string, int >, Interval > FuncValueBounds
Definition Bounds.h:17
void merge_boxes(Box &a, const Box &b)
Expand box a to encompass box b.
bool boxes_overlap(const Box &a, const Box &b)
Test if box a could possibly overlap box b.
std::map< std::string, Box > boxes_required(const Expr &e, const Scope< Interval > &scope=Scope< Interval >::empty_scope(), const FuncValueBounds &func_bounds=empty_func_value_bounds())
Compute rectangular domains large enough to cover all the 'Call's to each function that occurs within...
Box box_provided(const Expr &e, const std::string &fn, const Scope< Interval > &scope=Scope< Interval >::empty_scope(), const FuncValueBounds &func_bounds=empty_func_value_bounds())
Box box_union(const Box &a, const Box &b)
The union of two boxes.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
A fragment of Halide syntax.
Definition Expr.h:258
Represents the bounds of a region of arbitrary dimension.
Definition Bounds.h:53
bool maybe_unused() const
Check if the used condition is defined and not trivially true.
Box(size_t sz)
Definition Bounds.h:61
const Interval & operator[](size_t i) const
Definition Bounds.h:77
size_t size() const
Definition Bounds.h:68
Expr used
The conditions under which this region may be touched.
Definition Bounds.h:55
void push_back(const Interval &i)
Definition Bounds.h:83
friend std::ostream & operator<<(std::ostream &stream, const Box &b)
void resize(size_t sz)
Definition Bounds.h:80
Box(const std::vector< Interval > &b)
Definition Bounds.h:64
std::vector< Interval > bounds
The bounds if it is touched.
Definition Bounds.h:58
Interval & operator[](size_t i)
Definition Bounds.h:74
bool empty() const
Definition Bounds.h:71
A class to represent ranges of Exprs.
Definition Interval.h:14
A reference-counted handle to a statement node.
Definition Expr.h:427