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 
8 #include "IR.h"
9 
10 namespace Halide {
11 
12 /** A Halide variable, to be used when defining functions. It is just
13  * a name, and can be reused in places where no name conflict will
14  * occur. It can be used in the left-hand-side of a function
15  * definition, or as an Expr. As an Expr, it always has type
16  * Int(32). */
17 class Var {
18  std::string _name;
19 public:
20  /** Construct a Var with the given name */
21  EXPORT Var(const std::string &n);
22 
23  /** Construct a Var with an automatically-generated unique name. */
24  EXPORT Var();
25 
26  /** Get the name of a Var */
27  const std::string &name() const {return _name;}
28 
29  /** Test if two Vars are the same. This simply compares the names. */
30  bool same_as(const Var &other) const {return _name == other._name;}
31 
32  /** Implicit var constructor. Implicit variables are injected
33  * automatically into a function call if the number of arguments
34  * to the function are fewer than its dimensionality and a
35  * placeholder ("_") appears in its argument list. Defining a
36  * function to equal an expression containing implicit variables
37  * similarly appends those implicit variables, in the same order,
38  * to the left-hand-side of the definition where the placeholder
39  * ('_') appears.
40  *
41  * For example, consider the definition:
42  *
43  \code
44  Func f, g;
45  Var x, y;
46  f(x, y) = 3;
47  \endcode
48  *
49  * A call to f with the placeholder symbol \ref _
50  * will have implicit arguments injected automatically, so f(2, \ref _)
51  * is equivalent to f(2, \ref _0), where \ref _0 = Var::implicit(0), and f(\ref _)
52  * (and indeed f when cast to an Expr) is equivalent to f(\ref _0, \ref _1).
53  * The following definitions are all equivalent, differing only in the
54  * variable names.
55  *
56  \code
57  g(_) = f*3;
58  g(_) = f(_)*3;
59  g(x, _) = f(x, _)*3;
60  g(x, y) = f(x, y)*3;
61  \endcode
62  *
63  * These are expanded internally as follows:
64  *
65  \code
66  g(_0, _1) = f(_0, _1)*3;
67  g(_0, _1) = f(_0, _1)*3;
68  g(x, _0) = f(x, _0)*3;
69  g(x, y) = f(x, y)*3;
70  \endcode
71  *
72  * The following, however, defines g as four dimensional:
73  \code
74  g(x, y, _) = f*3;
75  \endcode
76  *
77  * It is equivalent to:
78  *
79  \code
80  g(x, y, _0, _1) = f(_0, _1)*3;
81  \endcode
82  *
83  * Expressions requiring differing numbers of implicit variables
84  * can be combined. The left-hand-side of a definition injects
85  * enough implicit variables to cover all of them:
86  *
87  \code
88  Func h;
89  h(x) = x*3;
90  g(x) = h + (f + f(x)) * f(x, y);
91  \endcode
92  *
93  * expands to:
94  *
95  \code
96  Func h;
97  h(x) = x*3;
98  g(x, _0, _1) = h(_0) + (f(_0, _1) + f(x, _0)) * f(x, y);
99  \endcode
100  *
101  * The first ten implicits, _0 through _9, are predeclared in this
102  * header and can be used for scheduling. They should never be
103  * used as arguments in a declaration or used in a call.
104  *
105  * While it is possible to use Var::implicit or the predeclared
106  * implicits to create expressions that can be treated as small
107  * anonymous functions (e.g. Func(_0 + _1)) this is considered
108  * poor style. Instead use \ref lambda.
109  */
110  EXPORT static Var implicit(int n);
111 
112  /** Return whether a variable name is of the form for an implicit argument.
113  * TODO: This is almost guaranteed to incorrectly fire on user
114  * declared variables at some point. We should likely prevent
115  * user Var declarations from making names of this form.
116  */
117  //{
118  EXPORT static bool is_implicit(const std::string &name);
119  bool is_implicit() const {
120  return is_implicit(name());
121  }
122  //}
123 
124  /** Return the argument index for a placeholder argument given its
125  * name. Returns 0 for \ref _0, 1 for \ref _1, etc. Returns -1 if
126  * the variable is not of implicit form.
127  */
128  //{
129  static int implicit_index(const std::string &name) {
130  return is_implicit(name) ? atoi(name.c_str() + 1) : -1;
131  }
132  int implicit_index() const {
133  return implicit_index(name());
134  }
135  //}
136 
137  /** Test if a var is the placeholder variable \ref _ */
138  //{
139  static bool is_placeholder(const std::string &name) {
140  return name == "_";
141  }
142  bool is_placeholder() const {
143  return is_placeholder(name());
144  }
145  //}
146 
147  /** A Var can be treated as an Expr of type Int(32) */
148  operator Expr() const {
149  return Internal::Variable::make(Int(32), name());
150  }
151 
152  /** Vars to use for scheduling producer/consumer pairs on the gpu. Deprecated. */
153  // @{
154  HALIDE_ATTRIBUTE_DEPRECATED("Var::gpu_blocks() is deprecated.")
155  static Var gpu_blocks() {
156  return Var("__deprecated_block_id_x");
157  }
158  HALIDE_ATTRIBUTE_DEPRECATED("Var::gpu_threads() is deprecated.")
159  static Var gpu_threads() {
160  return Var("__deprecated_thread_id_x");
161  }
162  // @}
163 
164  /** A Var that represents the location outside the outermost loop. */
165  static Var outermost() {
166  return Var("__outermost");
167  }
168 
169 };
170 
171 /** A placeholder variable for infered arguments. See \ref Var::implicit */
172 EXPORT extern Var _;
173 
174 /** The first ten implicit Vars for use in scheduling. See \ref Var::implicit */
175 // @{
176 EXPORT extern Var _0, _1, _2, _3, _4, _5, _6, _7, _8, _9;
177 // @}
178 
179 }
180 
181 #endif
static Var outermost()
A Var that represents the location outside the outermost loop.
Definition: Var.h:165
A fragment of Halide syntax.
Definition: Expr.h:276
bool is_placeholder() const
Definition: Var.h:142
A Halide variable, to be used when defining functions.
Definition: Var.h:17
#define HALIDE_ATTRIBUTE_DEPRECATED(x)
EXPORT Var _6
The first ten implicit Vars for use in scheduling.
EXPORT Var _1
The first ten implicit Vars for use in scheduling.
Defines methods for manipulating and analyzing boolean expressions.
static Expr make(Type type, const std::string &name)
Definition: IR.h:622
EXPORT Var _2
The first ten implicit Vars for use in scheduling.
static Var gpu_threads()
Vars to use for scheduling producer/consumer pairs on the gpu.
Definition: Var.h:159
static int implicit_index(const std::string &name)
Return the argument index for a placeholder argument given its name.
Definition: Var.h:129
int atoi(const char *)
const std::string & name() const
Get the name of a Var.
Definition: Var.h:27
bool is_implicit() const
Definition: Var.h:119
bool same_as(const Var &other) const
Test if two Vars are the same.
Definition: Var.h:30
EXPORT Var _
A placeholder variable for infered arguments.
static EXPORT Var implicit(int n)
Implicit var constructor.
static Var gpu_blocks()
Vars to use for scheduling producer/consumer pairs on the gpu.
Definition: Var.h:155
EXPORT Var _8
The first ten implicit Vars for use in scheduling.
EXPORT Var()
Construct a Var with an automatically-generated unique name.
Subtypes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt) ...
EXPORT Var _5
The first ten implicit Vars for use in scheduling.
int implicit_index() const
Definition: Var.h:132
static bool is_placeholder(const std::string &name)
Test if a var is the placeholder variable _.
Definition: Var.h:139
EXPORT Var _7
The first ten implicit Vars for use in scheduling.
EXPORT Var _9
The first ten implicit Vars for use in scheduling.
#define EXPORT
Definition: Util.h:30
EXPORT Var _3
The first ten implicit Vars for use in scheduling.
EXPORT Var _4
The first ten implicit Vars for use in scheduling.
EXPORT Var _0
The first ten implicit Vars for use in scheduling.
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
Definition: Type.h:437