Halide 21.0.0
Halide compiler and libraries
Loading...
Searching...
No Matches
Var.h
Go to the documentation of this file.
1#ifndef HALIDE_VAR_H
2#define HALIDE_VAR_H
3
4/** \file
5 * Defines the Var - the front-end variable
6 */
7#include <string>
8#include <vector>
9
10#include "Expr.h"
11
12namespace Halide {
13
14/** A Halide variable, to be used when defining functions. It is just
15 * a name, and can be reused in places where no name conflict will
16 * occur. It can be used in the left-hand-side of a function
17 * definition, or as an Expr. As an Expr, it always has type
18 * Int(32). */
19class Var {
20 /* The expression representing the Var. Guaranteed to be an
21 * Internal::Variable of type Int(32). Created once on
22 * construction of the Var to avoid making a fresh Expr every time
23 * the Var is used in a context in which it will be converted to
24 * one. */
25 Expr e;
26
27public:
28 /** Construct a Var with the given name. Unlike Funcs, this will be treated
29 * as the same Var as another other Var with the same name, including
30 * implicit Vars. */
31 Var(const std::string &n);
32
33 /** Construct a Var with an automatically-generated unique name. */
34 Var();
35
36 /** Get the name of a Var */
37 const std::string &name() const;
38
39 /** Test if two Vars are the same. This simply compares the names. */
40 bool same_as(const Var &other) const {
41 return name() == other.name();
42 }
43
44 /** Implicit var constructor. Implicit variables are injected
45 * automatically into a function call if the number of arguments
46 * to the function are fewer than its dimensionality and a
47 * placeholder ("_") appears in its argument list. Defining a
48 * function to equal an expression containing implicit variables
49 * similarly appends those implicit variables, in the same order,
50 * to the left-hand-side of the definition where the placeholder
51 * ('_') appears.
52 *
53 * For example, consider the definition:
54 *
55 \code
56 Func f, g;
57 Var x, y;
58 f(x, y) = 3;
59 \endcode
60 *
61 * A call to f with the placeholder symbol _
62 * will have implicit arguments injected automatically, so f(2, _)
63 * is equivalent to f(2, _0), where _0 = ImplicitVar<0>(), and f(_)
64 * (and indeed f when cast to an Expr) is equivalent to f(_0, _1).
65 * The following definitions are all equivalent, differing only in the
66 * variable names.
67 *
68 \code
69 g(_) = f*3;
70 g(_) = f(_)*3;
71 g(x, _) = f(x, _)*3;
72 g(x, y) = f(x, y)*3;
73 \endcode
74 *
75 * These are expanded internally as follows:
76 *
77 \code
78 g(_0, _1) = f(_0, _1)*3;
79 g(_0, _1) = f(_0, _1)*3;
80 g(x, _0) = f(x, _0)*3;
81 g(x, y) = f(x, y)*3;
82 \endcode
83 *
84 * The following, however, defines g as four dimensional:
85 \code
86 g(x, y, _) = f*3;
87 \endcode
88 *
89 * It is equivalent to:
90 *
91 \code
92 g(x, y, _0, _1) = f(_0, _1)*3;
93 \endcode
94 *
95 * Expressions requiring differing numbers of implicit variables
96 * can be combined. The left-hand-side of a definition injects
97 * enough implicit variables to cover all of them:
98 *
99 \code
100 Func h;
101 h(x) = x*3;
102 g(x) = h + (f + f(x)) * f(x, y);
103 \endcode
104 *
105 * expands to:
106 *
107 \code
108 Func h;
109 h(x) = x*3;
110 g(x, _0, _1) = h(_0) + (f(_0, _1) + f(x, _0)) * f(x, y);
111 \endcode
112 *
113 * The first ten implicits, _0 through _9, are predeclared in this
114 * header and can be used for scheduling. They should never be
115 * used as arguments in a declaration or used in a call.
116 *
117 * While it is possible to use Var::implicit or the predeclared
118 * implicits to create expressions that can be treated as small
119 * anonymous functions (e.g. Func(_0 + _1)) this is considered
120 * poor style. Instead use \ref lambda.
121 */
122 static Var implicit(int n);
123
124 /** Return whether a variable name is of the form for an implicit argument.
125 */
126 //{
127 static bool is_implicit(const std::string &name);
128 bool is_implicit() const {
129 return is_implicit(name());
130 }
131 //}
132
133 /** Return the argument index for a placeholder argument given its
134 * name. Returns 0 for _0, 1 for _1, etc. Returns -1 if
135 * the variable is not of implicit form.
136 */
137 //{
138 static int implicit_index(const std::string &name) {
139 return is_implicit(name) ? atoi(name.c_str() + 1) : -1;
140 }
141 int implicit_index() const {
142 return implicit_index(name());
143 }
144 //}
145
146 /** Test if a var is the placeholder variable _ */
147 //{
148 static bool is_placeholder(const std::string &name) {
149 return name == "_";
150 }
151 bool is_placeholder() const {
152 return is_placeholder(name());
153 }
154 //}
155
156 /** A Var can be treated as an Expr of type Int(32) */
157 operator const Expr &() const {
158 return e;
159 }
160
161 /** A Var that represents the location outside the outermost loop. */
162 static Var outermost() {
163 return Var("__outermost");
164 }
165};
166
167template<int N = -1>
169 Var to_var() const {
170 if (N >= 0) {
171 return Var::implicit(N);
172 } else {
173 return Var("_");
174 }
175 }
176
177 operator Var() const {
178 return to_var();
179 }
180 operator Expr() const {
181 return to_var();
182 }
183};
184
185/** A placeholder variable for inferred arguments. See \ref Var::implicit */
186static constexpr ImplicitVar<> _;
187
188/** The first ten implicit Vars for use in scheduling. See \ref Var::implicit */
189// @{
190static constexpr ImplicitVar<0> _0;
191static constexpr ImplicitVar<1> _1;
192static constexpr ImplicitVar<2> _2;
193static constexpr ImplicitVar<3> _3;
194static constexpr ImplicitVar<4> _4;
195static constexpr ImplicitVar<5> _5;
196static constexpr ImplicitVar<6> _6;
197static constexpr ImplicitVar<7> _7;
198static constexpr ImplicitVar<8> _8;
199static constexpr ImplicitVar<9> _9;
200// @}
201
202namespace Internal {
203
204/** Make a list of unique arguments for definitions with unnamed
205 arguments. */
206std::vector<Var> make_argument_list(int dimensionality);
207
208} // namespace Internal
209
210} // namespace Halide
211
212#endif
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
A Halide variable, to be used when defining functions.
Definition Var.h:19
Var(const std::string &n)
Construct a Var with the given name.
static Var implicit(int n)
Implicit var constructor.
static int implicit_index(const std::string &name)
Return the argument index for a placeholder argument given its name.
Definition Var.h:138
bool is_placeholder() const
Definition Var.h:151
const std::string & name() const
Get the name of a Var.
bool is_implicit() const
Definition Var.h:128
static bool is_placeholder(const std::string &name)
Test if a var is the placeholder variable _.
Definition Var.h:148
static bool is_implicit(const std::string &name)
Return whether a variable name is of the form for an implicit argument.
int implicit_index() const
Definition Var.h:141
static Var outermost()
A Var that represents the location outside the outermost loop.
Definition Var.h:162
Var()
Construct a Var with an automatically-generated unique name.
bool same_as(const Var &other) const
Test if two Vars are the same.
Definition Var.h:40
std::vector< Var > make_argument_list(int dimensionality)
Make a list of unique arguments for definitions with unnamed arguments.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
int atoi(const char *)
A fragment of Halide syntax.
Definition Expr.h:258
Var to_var() const
Definition Var.h:169