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