Halide
IROperator.h
Go to the documentation of this file.
1 #ifndef HALIDE_IR_OPERATOR_H
2 #define HALIDE_IR_OPERATOR_H
3 
4 /** \file
5  *
6  * Defines various operator overloads and utility functions that make
7  * it more pleasant to work with Halide expressions.
8  */
9 
10 #include <atomic>
11 
12 #include "IR.h"
13 #include "Util.h"
14 
15 namespace Halide {
16 
17 namespace Internal {
18 /** Is the expression either an IntImm, a FloatImm, a StringImm, or a
19  * Cast of the same, or a Ramp or Broadcast of the same. Doesn't do
20  * any constant folding. */
21 EXPORT bool is_const(const Expr &e);
22 
23 /** Is the expression an IntImm, FloatImm of a particular value, or a
24  * Cast, or Broadcast of the same. */
25 EXPORT bool is_const(const Expr &e, int64_t v);
26 
27 /** If an expression is an IntImm or a Broadcast of an IntImm, return
28  * a pointer to its value. Otherwise returns nullptr. */
29 EXPORT const int64_t *as_const_int(const Expr &e);
30 
31 /** If an expression is a UIntImm or a Broadcast of a UIntImm, return
32  * a pointer to its value. Otherwise returns nullptr. */
33 EXPORT const uint64_t *as_const_uint(const Expr &e);
34 
35 /** If an expression is a FloatImm or a Broadcast of a FloatImm,
36  * return a pointer to its value. Otherwise returns nullptr. */
37 EXPORT const double *as_const_float(const Expr &e);
38 
39 /** Is the expression a constant integer power of two. Also returns
40  * log base two of the expression if it is. Only returns true for
41  * integer types. */
42 EXPORT bool is_const_power_of_two_integer(const Expr &e, int *bits);
43 
44 /** Is the expression a const (as defined by is_const), and also
45  * strictly greater than zero (in all lanes, if a vector expression) */
46 EXPORT bool is_positive_const(const Expr &e);
47 
48 /** Is the expression a const (as defined by is_const), and also
49  * strictly less than zero (in all lanes, if a vector expression) */
50 EXPORT bool is_negative_const(const Expr &e);
51 
52 /** Is the expression a const (as defined by is_const), and also
53  * strictly less than zero (in all lanes, if a vector expression) and
54  * is its negative value representable. (This excludes the most
55  * negative value of the Expr's type from inclusion. Intended to be
56  * used when the value will be negated as part of simplification.)
57  */
58 EXPORT bool is_negative_negatable_const(const Expr &e);
59 
60 /** Is the expression an undef */
61 EXPORT bool is_undef(const Expr &e);
62 
63 /** Is the expression a const (as defined by is_const), and also equal
64  * to zero (in all lanes, if a vector expression) */
65 EXPORT bool is_zero(const Expr &e);
66 
67 /** Is the expression a const (as defined by is_const), and also equal
68  * to one (in all lanes, if a vector expression) */
69 EXPORT bool is_one(const Expr &e);
70 
71 /** Is the expression a const (as defined by is_const), and also equal
72  * to two (in all lanes, if a vector expression) */
73 EXPORT bool is_two(const Expr &e);
74 
75 /** Is the statement a no-op (which we represent as either an
76  * undefined Stmt, or as an Evaluate node of a constant) */
77 EXPORT bool is_no_op(const Stmt &s);
78 
79 /** Does the expression
80  * 1) Take on the same value no matter where it appears in a Stmt, and
81  * 2) Evaluating it has no side-effects
82  */
83 bool is_pure(const Expr &e);
84 
85 /** Construct an immediate of the given type from any numeric C++ type. */
86 // @{
87 EXPORT Expr make_const(Type t, int64_t val);
88 EXPORT Expr make_const(Type t, uint64_t val);
89 EXPORT Expr make_const(Type t, double val);
90 inline Expr make_const(Type t, int32_t val) {return make_const(t, (int64_t)val);}
91 inline Expr make_const(Type t, uint32_t val) {return make_const(t, (uint64_t)val);}
92 inline Expr make_const(Type t, int16_t val) {return make_const(t, (int64_t)val);}
93 inline Expr make_const(Type t, uint16_t val) {return make_const(t, (uint64_t)val);}
94 inline Expr make_const(Type t, int8_t val) {return make_const(t, (int64_t)val);}
95 inline Expr make_const(Type t, uint8_t val) {return make_const(t, (uint64_t)val);}
96 inline Expr make_const(Type t, bool val) {return make_const(t, (uint64_t)val);}
97 inline Expr make_const(Type t, float val) {return make_const(t, (double)val);}
98 inline Expr make_const(Type t, float16_t val) {return make_const(t, (double)val);}
99 // @}
100 
101 /** Check if a constant value can be correctly represented as the given type. */
103 
104 /** Construct a boolean constant from a C++ boolean value.
105  * May also be a vector if width is given.
106  * It is not possible to coerce a C++ boolean to Expr because
107  * if we provide such a path then char objects can ambiguously
108  * be converted to Halide Expr or to std::string. The problem
109  * is that C++ does not have a real bool type - it is in fact
110  * close enough to char that C++ does not know how to distinguish them.
111  * make_bool is the explicit coercion. */
112 EXPORT Expr make_bool(bool val, int lanes = 1);
113 
114 /** Construct the representation of zero in the given type */
116 
117 /** Construct the representation of one in the given type */
119 
120 /** Construct the representation of two in the given type */
122 
123 /** Construct the constant boolean true. May also be a vector of
124  * trues, if a lanes argument is given. */
125 EXPORT Expr const_true(int lanes = 1);
126 
127 /** Construct the constant boolean false. May also be a vector of
128  * falses, if a lanes argument is given. */
129 EXPORT Expr const_false(int lanes = 1);
130 
131 /** Attempt to cast an expression to a smaller type while provably not
132  * losing information. If it can't be done, return an undefined
133  * Expr. */
135 
136 /** Coerce the two expressions to have the same type, using C-style
137  * casting rules. For the purposes of casting, a boolean type is
138  * UInt(1). We use the following procedure:
139  *
140  * If the types already match, do nothing.
141  *
142  * Then, if one type is a vector and the other is a scalar, the scalar
143  * is broadcast to match the vector width, and we continue.
144  *
145  * Then, if one type is floating-point and the other is not, the
146  * non-float is cast to the floating-point type, and we're done.
147  *
148  * Then, if both types are unsigned ints, the one with fewer bits is
149  * cast to match the one with more bits and we're done.
150  *
151  * Then, if both types are signed ints, the one with fewer bits is
152  * cast to match the one with more bits and we're done.
153  *
154  * Finally, if one type is an unsigned int and the other type is a signed
155  * int, both are cast to a signed int with the greater of the two
156  * bit-widths. For example, matching an Int(8) with a UInt(16) results
157  * in an Int(16).
158  *
159  */
160 EXPORT void match_types(Expr &a, Expr &b);
161 
162 /** Halide's vectorizable transcendentals. */
163 // @{
167 // @}
168 
169 /** Raise an expression to an integer power by repeatedly multiplying
170  * it by itself. */
172 
173 /** Split a boolean condition into vector of ANDs. If 'cond' is undefined,
174  * return an empty vector. */
175 EXPORT void split_into_ands(const Expr &cond, std::vector<Expr> &result);
176 
177 /** A builder to help create Exprs representing halide_buffer_t
178  * structs (e.g. foo.buffer) via calls to halide_buffer_init. Fill out
179  * the fields and then call build. The resulting Expr will be a call
180  * to halide_buffer_init with the struct members as arguments. If the
181  * buffer_memory field is undefined, it uses a call to alloca to make
182  * some stack memory for the buffer. If the shape_memory field is
183  * undefined, it similarly uses stack memory for the shape. If the
184  * shape_memory field is null, it uses the dim field already in the
185  * buffer. Other unitialized fields will take on a value of zero in
186  * the constructed buffer. */
191  int dimensions = 0;
192  std::vector<Expr> mins, extents, strides;
194  EXPORT Expr build() const;
195 };
196 
197 /** If e is a ramp expression with stride, default 1, return the base,
198  * otherwise undefined. */
199 Expr strided_ramp_base(Expr e, int stride = 1);
200 
201 } // namespace Internal
202 
203 /** Cast an expression to the halide type corresponding to the C++ type T. */
204 template<typename T>
205 inline Expr cast(Expr a) {
206  return cast(type_of<T>(), std::move(a));
207 }
208 
209 /** Cast an expression to a new type. */
210 inline Expr cast(Type t, Expr a) {
211  user_assert(a.defined()) << "cast of undefined Expr\n";
212  if (a.type() == t) {
213  return a;
214  }
215 
216  if (t.is_handle() && !a.type().is_handle()) {
217  user_error << "Can't cast \"" << a << "\" to a handle. "
218  << "The only legal cast from scalar types to a handle is: "
219  << "reinterpret(Handle(), cast<uint64_t>(" << a << "));\n";
220  } else if (a.type().is_handle() && !t.is_handle()) {
221  user_error << "Can't cast handle \"" << a << "\" to type " << t << ". "
222  << "The only legal cast from handles to scalar types is: "
223  << "reinterpret(UInt(64), " << a << ");\n";
224  }
225 
226  // Fold constants early
227  if (const int64_t *i = as_const_int(a)) {
228  return Internal::make_const(t, *i);
229  }
230  if (const uint64_t *u = as_const_uint(a)) {
231  return Internal::make_const(t, *u);
232  }
233  if (const double *f = as_const_float(a)) {
234  return Internal::make_const(t, *f);
235  }
236 
237  if (t.is_vector()) {
238  if (a.type().is_scalar()) {
239  return Internal::Broadcast::make(cast(t.element_of(), std::move(a)), t.lanes());
240  } else if (const Internal::Broadcast *b = a.as<Internal::Broadcast>()) {
241  internal_assert(b->lanes == t.lanes());
242  return Internal::Broadcast::make(cast(t.element_of(), b->value), t.lanes());
243  }
244  }
245  return Internal::Cast::make(t, std::move(a));
246 }
247 
248 /** Return the sum of two expressions, doing any necessary type
249  * coercion using \ref Internal::match_types */
250 inline Expr operator+(Expr a, Expr b) {
251  user_assert(a.defined() && b.defined()) << "operator+ of undefined Expr\n";
252  Internal::match_types(a, b);
253  return Internal::Add::make(std::move(a), std::move(b));
254 }
255 
256 /** Add an expression and a constant integer. Coerces the type of the
257  * integer to match the type of the expression. Errors if the integer
258  * cannot be represented in the type of the expression. */
259 // @{
260 inline Expr operator+(Expr a, int b) {
261  user_assert(a.defined()) << "operator+ of undefined Expr\n";
262  Type t = a.type();
264  return Internal::Add::make(std::move(a), Internal::make_const(t, b));
265 }
266 
267 /** Add a constant integer and an expression. Coerces the type of the
268  * integer to match the type of the expression. Errors if the integer
269  * cannot be represented in the type of the expression. */
270 inline Expr operator+(int a, Expr b) {
271  user_assert(b.defined()) << "operator+ of undefined Expr\n";
272  Type t = b.type();
274  return Internal::Add::make(Internal::make_const(t, a), std::move(b));
275 }
276 
277 /** Modify the first expression to be the sum of two expressions,
278  * without changing its type. This casts the second argument to match
279  * the type of the first. */
280 inline Expr &operator+=(Expr &a, Expr b) {
281  user_assert(a.defined() && b.defined()) << "operator+= of undefined Expr\n";
282  Type t = a.type();
283  a = Internal::Add::make(std::move(a), cast(t, std::move(b)));
284  return a;
285 }
286 
287 /** Return the difference of two expressions, doing any necessary type
288  * coercion using \ref Internal::match_types */
289 inline Expr operator-(Expr a, Expr b) {
290  user_assert(a.defined() && b.defined()) << "operator- of undefined Expr\n";
291  Internal::match_types(a, b);
292  return Internal::Sub::make(std::move(a), std::move(b));
293 }
294 
295 /** Subtracts a constant integer from an expression. Coerces the type of the
296  * integer to match the type of the expression. Errors if the integer
297  * cannot be represented in the type of the expression. */
298 inline Expr operator-(Expr a, int b) {
299  user_assert(a.defined()) << "operator- of undefined Expr\n";
300  Type t = a.type();
302  return Internal::Sub::make(std::move(a), Internal::make_const(t, b));
303 }
304 
305 /** Subtracts an expression from a constant integer. Coerces the type
306  * of the integer to match the type of the expression. Errors if the
307  * integer cannot be represented in the type of the expression. */
308 inline Expr operator-(int a, Expr b) {
309  user_assert(b.defined()) << "operator- of undefined Expr\n";
310  Type t = b.type();
312  return Internal::Sub::make(Internal::make_const(t, a), std::move(b));
313 }
314 
315 /** Return the negative of the argument. Does no type casting, so more
316  * formally: return that number which when added to the original,
317  * yields zero of the same type. For unsigned integers the negative is
318  * still an unsigned integer. E.g. in UInt(8), the negative of 56 is
319  * 200, because 56 + 200 == 0 */
320 inline Expr operator-(Expr a) {
321  user_assert(a.defined()) << "operator- of undefined Expr\n";
322  Type t = a.type();
323  return Internal::Sub::make(Internal::make_zero(t), std::move(a));
324 }
325 
326 /** Modify the first expression to be the difference of two expressions,
327  * without changing its type. This casts the second argument to match
328  * the type of the first. */
329 inline Expr &operator-=(Expr &a, Expr b) {
330  user_assert(a.defined() && b.defined()) << "operator-= of undefined Expr\n";
331  Type t = a.type();
332  a = Internal::Sub::make(std::move(a), cast(t, std::move(b)));
333  return a;
334 }
335 
336 /** Return the product of two expressions, doing any necessary type
337  * coercion using \ref Internal::match_types */
338 inline Expr operator*(Expr a, Expr b) {
339  user_assert(a.defined() && b.defined()) << "operator* of undefined Expr\n";
340  Internal::match_types(a, b);
341  return Internal::Mul::make(std::move(a), std::move(b));
342 }
343 
344 /** Multiply an expression and a constant integer. Coerces the type of the
345  * integer to match the type of the expression. Errors if the integer
346  * cannot be represented in the type of the expression. */
347 inline Expr operator*(const Expr &a, int b) {
348  user_assert(a.defined()) << "operator* of undefined Expr\n";
349  Type t = a.type();
351  return Internal::Mul::make(std::move(a), Internal::make_const(t, b));
352 }
353 
354 /** Multiply a constant integer and an expression. Coerces the type of
355  * the integer to match the type of the expression. Errors if the
356  * integer cannot be represented in the type of the expression. */
357 inline Expr operator*(int a, Expr b) {
358  user_assert(b.defined()) << "operator* of undefined Expr\n";
359  Type t = b.type();
361  return Internal::Mul::make(Internal::make_const(t, a), std::move(b));
362 }
363 
364 /** Modify the first expression to be the product of two expressions,
365  * without changing its type. This casts the second argument to match
366  * the type of the first. */
367 inline Expr &operator*=(Expr &a, Expr b) {
368  user_assert(a.defined() && b.defined()) << "operator*= of undefined Expr\n";
369  Type t = a.type();
370  a = Internal::Mul::make(std::move(a), cast(t, std::move(b)));
371  return a;
372 }
373 
374 /** Return the ratio of two expressions, doing any necessary type
375  * coercion using \ref Internal::match_types. Note that signed integer
376  * division in Halide rounds towards minus infinity, unlike C, which
377  * rounds towards zero. */
378 inline Expr operator/(Expr a, Expr b) {
379  user_assert(a.defined() && b.defined()) << "operator/ of undefined Expr\n";
380  Internal::match_types(a, b);
381  return Internal::Div::make(std::move(a), std::move(b));
382 }
383 
384 /** Modify the first expression to be the ratio of two expressions,
385  * without changing its type. This casts the second argument to match
386  * the type of the first. Note that signed integer division in Halide
387  * rounds towards minus infinity, unlike C, which rounds towards
388  * zero. */
389 inline Expr &operator/=(Expr &a, Expr b) {
390  user_assert(a.defined() && b.defined()) << "operator/= of undefined Expr\n";
391  Type t = a.type();
392  a = Internal::Div::make(std::move(a), cast(t, std::move(b)));
393  return a;
394 }
395 
396 /** Divides an expression by a constant integer. Coerces the type
397  * of the integer to match the type of the expression. Errors if the
398  * integer cannot be represented in the type of the expression. */
399 inline Expr operator/(Expr a, int b) {
400  user_assert(a.defined()) << "operator/ of undefined Expr\n";
401  Type t = a.type();
403  return Internal::Div::make(std::move(a), Internal::make_const(t, b));
404 }
405 
406 /** Divides a constant integer by an expression. Coerces the type
407  * of the integer to match the type of the expression. Errors if the
408  * integer cannot be represented in the type of the expression. */
409 inline Expr operator/(int a, Expr b) {
410  user_assert(b.defined()) << "operator- of undefined Expr\n";
411  Type t = b.type();
413  return Internal::Div::make(Internal::make_const(t, a), std::move(b));
414 }
415 
416 /** Return the first argument reduced modulo the second, doing any
417  * necessary type coercion using \ref Internal::match_types. For
418  * signed integers, the sign of the result matches the sign of the
419  * second argument (unlike in C, where it matches the sign of the
420  * first argument). For example, this means that x%2 is always either
421  * zero or one, even if x is negative.*/
422 inline Expr operator%(Expr a, Expr b) {
423  user_assert(a.defined() && b.defined()) << "operator% of undefined Expr\n";
424  user_assert(!Internal::is_zero(b)) << "operator% with constant 0 modulus\n";
425  Internal::match_types(a, b);
426  return Internal::Mod::make(std::move(a), std::move(b));
427 }
428 
429 /** Mods an expression by a constant integer. Coerces the type
430  * of the integer to match the type of the expression. Errors if the
431  * integer cannot be represented in the type of the expression. */
432 inline Expr operator%(Expr a, int b) {
433  user_assert(a.defined()) << "operator% of undefined Expr\n";
434  user_assert(b != 0) << "operator% with constant 0 modulus\n";
435  Type t = a.type();
437  return Internal::Mod::make(std::move(a), Internal::make_const(t, b));
438 }
439 /** Mods a constant integer by an expression. Coerces the type
440  * of the integer to match the type of the expression. Errors if the
441  * integer cannot be represented in the type of the expression. */
442 inline Expr operator%(int a, const Expr &b) {
443  user_assert(b.defined()) << "operator% of undefined Expr\n";
444  user_assert(!Internal::is_zero(b)) << "operator% with constant 0 modulus\n";
445  Type t = b.type();
447  return Internal::Mod::make(Internal::make_const(t, a), std::move(b));
448 }
449 
450 /** Return a boolean expression that tests whether the first argument
451  * is greater than the second, after doing any necessary type coercion
452  * using \ref Internal::match_types */
453 inline Expr operator>(Expr a, Expr b) {
454  user_assert(a.defined() && b.defined()) << "operator> of undefined Expr\n";
455  Internal::match_types(a, b);
456  return Internal::GT::make(std::move(a), std::move(b));
457 }
458 
459 /** Return a boolean expression that tests whether an expression is
460  * greater than a constant integer. Coerces the integer to the type of
461  * the expression. Errors if the integer is not representable in that
462  * type. */
463 inline Expr operator>(Expr a, int b) {
464  user_assert(a.defined()) << "operator> of undefined Expr\n";
465  Type t = a.type();
467  return Internal::GT::make(std::move(a), Internal::make_const(t, b));
468 }
469 
470 /** Return a boolean expression that tests whether a constant integer is
471  * greater than an expression. Coerces the integer to the type of
472  * the expression. Errors if the integer is not representable in that
473  * type. */
474 inline Expr operator>(int a, Expr b) {
475  user_assert(b.defined()) << "operator> of undefined Expr\n";
476  Type t = b.type();
478  return Internal::GT::make(Internal::make_const(t, a), std::move(b));
479 }
480 
481 /** Return a boolean expression that tests whether the first argument
482  * is less than the second, after doing any necessary type coercion
483  * using \ref Internal::match_types */
484 inline Expr operator<(Expr a, Expr b) {
485  user_assert(a.defined() && b.defined()) << "operator< of undefined Expr\n";
486  Internal::match_types(a, b);
487  return Internal::LT::make(std::move(a), std::move(b));
488 }
489 
490 /** Return a boolean expression that tests whether an expression is
491  * less than a constant integer. Coerces the integer to the type of
492  * the expression. Errors if the integer is not representable in that
493  * type. */
494 inline Expr operator<(Expr a, int b) {
495  user_assert(a.defined()) << "operator< of undefined Expr\n";
496  Type t = a.type();
498  return Internal::LT::make(std::move(a), Internal::make_const(t, b));
499 }
500 
501 /** Return a boolean expression that tests whether a constant integer is
502  * less than an expression. Coerces the integer to the type of
503  * the expression. Errors if the integer is not representable in that
504  * type. */
505 inline Expr operator<(int a, Expr b) {
506  user_assert(b.defined()) << "operator< of undefined Expr\n";
507  Type t = b.type();
509  return Internal::LT::make(Internal::make_const(t, a), std::move(b));
510 }
511 
512 /** Return a boolean expression that tests whether the first argument
513  * is less than or equal to the second, after doing any necessary type
514  * coercion using \ref Internal::match_types */
516  user_assert(a.defined() && b.defined()) << "operator<= of undefined Expr\n";
517  Internal::match_types(a, b);
518  return Internal::LE::make(std::move(a), std::move(b));
519 }
520 
521 /** Return a boolean expression that tests whether an expression is
522  * less than or equal to a constant integer. Coerces the integer to
523  * the type of the expression. Errors if the integer is not
524  * representable in that type. */
525 inline Expr operator<=(Expr a, int b) {
526  user_assert(a.defined()) << "operator<= of undefined Expr\n";
527  Type t = a.type();
529  return Internal::LE::make(std::move(a), Internal::make_const(t, b));
530 }
531 
532 /** Return a boolean expression that tests whether a constant integer
533  * is less than or equal to an expression. Coerces the integer to the
534  * type of the expression. Errors if the integer is not representable
535  * in that type. */
536 inline Expr operator<=(int a, Expr b) {
537  user_assert(b.defined()) << "operator<= of undefined Expr\n";
538  Type t = b.type();
540  return Internal::LE::make(Internal::make_const(t, a), std::move(b));
541 }
542 
543 /** Return a boolean expression that tests whether the first argument
544  * is greater than or equal to the second, after doing any necessary
545  * type coercion using \ref Internal::match_types */
547  user_assert(a.defined() && b.defined()) << "operator>= of undefined Expr\n";
548  Internal::match_types(a, b);
549  return Internal::GE::make(std::move(a), std::move(b));
550 }
551 
552 /** Return a boolean expression that tests whether an expression is
553  * greater than or equal to a constant integer. Coerces the integer to
554  * the type of the expression. Errors if the integer is not
555  * representable in that type. */
556 inline Expr operator>=(Expr a, int b) {
557  user_assert(a.defined()) << "operator>= of undefined Expr\n";
558  Type t = a.type();
560  return Internal::GE::make(a, Internal::make_const(t, b));
561 }
562 
563 /** Return a boolean expression that tests whether a constant integer
564  * is greater than or equal to an expression. Coerces the integer to the
565  * type of the expression. Errors if the integer is not representable
566  * in that type. */
567 inline Expr operator>=(int a, Expr b) {
568  user_assert(b.defined()) << "operator>= of undefined Expr\n";
569  Type t = b.type();
571  return Internal::GE::make(Internal::make_const(t, a), b);
572 }
573 
574 /** Return a boolean expression that tests whether the first argument
575  * is equal to the second, after doing any necessary type coercion
576  * using \ref Internal::match_types */
578  user_assert(a.defined() && b.defined()) << "operator== of undefined Expr\n";
579  Internal::match_types(a, b);
580  return Internal::EQ::make(std::move(a), std::move(b));
581 }
582 
583 /** Return a boolean expression that tests whether an expression is
584  * equal to a constant integer. Coerces the integer to the type of the
585  * expression. Errors if the integer is not representable in that
586  * type. */
587 inline Expr operator==(Expr a, int b) {
588  user_assert(a.defined()) << "operator== of undefined Expr\n";
589  Type t = a.type();
591  return Internal::EQ::make(std::move(a), Internal::make_const(t, b));
592 }
593 
594 /** Return a boolean expression that tests whether a constant integer
595  * is equal to an expression. Coerces the integer to the type of the
596  * expression. Errors if the integer is not representable in that
597  * type. */
598 inline Expr operator==(int a, Expr b) {
599  user_assert(b.defined()) << "operator== of undefined Expr\n";
600  Type t = b.type();
602  return Internal::EQ::make(Internal::make_const(t, a), std::move(b));
603 }
604 
605 /** Return a boolean expression that tests whether the first argument
606  * is not equal to the second, after doing any necessary type coercion
607  * using \ref Internal::match_types */
609  user_assert(a.defined() && b.defined()) << "operator!= of undefined Expr\n";
610  Internal::match_types(a, b);
611  return Internal::NE::make(std::move(a), std::move(b));
612 }
613 
614 /** Return a boolean expression that tests whether an expression is
615  * not equal to a constant integer. Coerces the integer to the type of
616  * the expression. Errors if the integer is not representable in that
617  * type. */
618 inline Expr operator!=(Expr a, int b) {
619  user_assert(a.defined()) << "operator!= of undefined Expr\n";
620  Type t = a.type();
622  return Internal::NE::make(std::move(a), Internal::make_const(t, b));
623 }
624 
625 /** Return a boolean expression that tests whether a constant integer
626  * is not equal to an expression. Coerces the integer to the type of
627  * the expression. Errors if the integer is not representable in that
628  * type. */
629 inline Expr operator!=(int a, Expr b) {
630  user_assert(b.defined()) << "operator!= of undefined Expr\n";
631  Type t = b.type();
633  return Internal::NE::make(Internal::make_const(t, a), std::move(b));
634 }
635 
636 /** Returns the logical and of the two arguments */
638  Internal::match_types(a, b);
639  return Internal::And::make(std::move(a), std::move(b));
640 }
641 
642 /** Logical and of an Expr and a bool. Either returns the Expr or an
643  * Expr representing false, depending on the bool. */
644 // @{
645 inline Expr operator&&(const Expr &a, bool b) {
646  internal_assert(a.defined()) << "operator&& of undefined Expr\n";
647  internal_assert(a.type().is_bool()) << "operator&& of Expr of type " << a.type() << "\n";
648  if (b) {
649  return a;
650  } else {
651  return Internal::make_zero(a.type());
652  }
653 }
654 inline Expr operator&&(bool a, const Expr &b) {
655  return std::move(b) && a;
656 }
657 // @}
658 
659 /** Returns the logical or of the two arguments */
661  Internal::match_types(a, b);
662  return Internal::Or::make(std::move(a), std::move(b));
663 }
664 
665 /** Logical or of an Expr and a bool. Either returns the Expr or an
666  * Expr representing true, depending on the bool. */
667 // @{
668 inline Expr operator||(const Expr &a, bool b) {
669  internal_assert(a.defined()) << "operator|| of undefined Expr\n";
670  internal_assert(a.type().is_bool()) << "operator|| of Expr of type " << a.type() << "\n";
671  if (b) {
672  return Internal::make_one(a.type());
673  } else {
674  return a;
675  }
676 }
677 inline Expr operator||(bool a, const Expr &b) {
678  return b || a;
679 }
680 // @}
681 
682 
683 /** Returns the logical not the argument */
684 inline Expr operator!(Expr a) {
685  return Internal::Not::make(std::move(a));
686 }
687 
688 /** Returns an expression representing the greater of the two
689  * arguments, after doing any necessary type coercion using
690  * \ref Internal::match_types. Vectorizes cleanly on most platforms
691  * (with the exception of integer types on x86 without SSE4). */
692 inline Expr max(Expr a, Expr b) {
693  user_assert(a.defined() && b.defined())
694  << "max of undefined Expr\n";
695  Internal::match_types(a, b);
696  return Internal::Max::make(std::move(a), std::move(b));
697 }
698 
699 /** Returns an expression representing the greater of an expression
700  * and a constant integer. The integer is coerced to the type of the
701  * expression. Errors if the integer is not representable as that
702  * type. Vectorizes cleanly on most platforms (with the exception of
703  * integer types on x86 without SSE4). */
704 inline Expr max(Expr a, int b) {
705  user_assert(a.defined()) << "max of undefined Expr\n";
706  Type t = a.type();
708  return Internal::Max::make(std::move(a), Internal::make_const(t, b));
709 }
710 
711 
712 /** Returns an expression representing the greater of a constant
713  * integer and an expression. The integer is coerced to the type of
714  * the expression. Errors if the integer is not representable as that
715  * type. Vectorizes cleanly on most platforms (with the exception of
716  * integer types on x86 without SSE4). */
717 inline Expr max(int a, Expr b) {
718  user_assert(b.defined()) << "max of undefined Expr\n";
719  Type t = b.type();
721  return Internal::Max::make(Internal::make_const(t, a), std::move(b));
722 }
723 
724 inline Expr max(float a, Expr b) {return max(Expr(a), std::move(b));}
725 inline Expr max(Expr a, float b) {return max(std::move(a), Expr(b));}
726 
727 /** Returns an expression representing the greater of an expressions
728  * vector, after doing any necessary type coersion using
729  * \ref Internal::match_types. Vectorizes cleanly on most platforms
730  * (with the exception of integer types on x86 without SSE4).
731  * The expressions are folded from right ie. max(.., max(.., ..)).
732  * The arguments can be any mix of types but must all be convertible to Expr. */
733 template<typename A, typename B, typename C, typename... Rest,
734  typename std::enable_if<Halide::Internal::all_are_convertible<Expr, Rest...>::value>::type* = nullptr>
735 inline Expr max(A &&a, B &&b, C &&c, Rest&&... rest) {
736  return max(std::forward<A>(a), max(std::forward<B>(b), std::forward<C>(c), std::forward<Rest>(rest)...));
737 }
738 
739 inline Expr min(Expr a, Expr b) {
740  user_assert(a.defined() && b.defined())
741  << "min of undefined Expr\n";
742  Internal::match_types(a, b);
743  return Internal::Min::make(std::move(a), std::move(b));
744 }
745 
746 /** Returns an expression representing the lesser of an expression
747  * and a constant integer. The integer is coerced to the type of the
748  * expression. Errors if the integer is not representable as that
749  * type. Vectorizes cleanly on most platforms (with the exception of
750  * integer types on x86 without SSE4). */
751 inline Expr min(Expr a, int b) {
752  user_assert(a.defined()) << "max of undefined Expr\n";
753  Type t = a.type();
755  return Internal::Min::make(std::move(a), Internal::make_const(t, b));
756 }
757 
758 /** Returns an expression representing the lesser of a constant
759  * integer and an expression. The integer is coerced to the type of
760  * the expression. Errors if the integer is not representable as that
761  * type. Vectorizes cleanly on most platforms (with the exception of
762  * integer types on x86 without SSE4). */
763 inline Expr min(int a, Expr b) {
764  user_assert(b.defined()) << "max of undefined Expr\n";
765  Type t = b.type();
767  return Internal::Min::make(Internal::make_const(t, a), std::move(b));
768 }
769 
770 inline Expr min(float a, Expr b) {return min(Expr(a), std::move(b));}
771 inline Expr min(Expr a, float b) {return min(std::move(a), Expr(b));}
772 
773 /** Returns an expression representing the lesser of an expressions
774  * vector, after doing any necessary type coersion using
775  * \ref Internal::match_types. Vectorizes cleanly on most platforms
776  * (with the exception of integer types on x86 without SSE4).
777  * The expressions are folded from right ie. min(.., min(.., ..)).
778  * The arguments can be any mix of types but must all be convertible to Expr. */
779 template<typename A, typename B, typename C, typename... Rest,
780  typename std::enable_if<Halide::Internal::all_are_convertible<Expr, Rest...>::value>::type* = nullptr>
781 inline Expr min(A &&a, B &&b, C &&c, Rest&&... rest) {
782  return min(std::forward<A>(a), min(std::forward<B>(b), std::forward<C>(c), std::forward<Rest>(rest)...));
783 }
784 
785 /** Operators on floats treats those floats as Exprs. Making these
786  * explicit prevents implicit float->int casts that might otherwise
787  * occur. */
788 // @{
789 inline Expr operator+(Expr a, float b) {return std::move(a) + Expr(b);}
790 inline Expr operator+(float a, Expr b) {return Expr(a) + std::move(b);}
791 inline Expr operator-(Expr a, float b) {return std::move(a) - Expr(b);}
792 inline Expr operator-(float a, Expr b) {return Expr(a) - std::move(b);}
793 inline Expr operator*(Expr a, float b) {return std::move(a) * Expr(b);}
794 inline Expr operator*(float a, Expr b) {return Expr(a) * std::move(b);}
795 inline Expr operator/(Expr a, float b) {return std::move(a) / Expr(b);}
796 inline Expr operator/(float a, Expr b) {return Expr(a) / std::move(b);}
797 inline Expr operator%(Expr a, float b) {return std::move(a) % Expr(b);}
798 inline Expr operator%(float a, Expr b) {return Expr(a) % std::move(b);}
799 inline Expr operator>(Expr a, float b) {return std::move(a) > Expr(b);}
800 inline Expr operator>(float a, Expr b) {return Expr(a) > std::move(b);}
801 inline Expr operator<(Expr a, float b) {return std::move(a) < Expr(b);}
802 inline Expr operator<(float a, Expr b) {return Expr(a) < std::move(b);}
803 inline Expr operator>=(Expr a, float b) {return std::move(a) >= Expr(b);}
804 inline Expr operator>=(float a, Expr b) {return Expr(a) >= std::move(b);}
805 inline Expr operator<=(Expr a, float b) {return std::move(a) <= Expr(b);}
806 inline Expr operator<=(float a, Expr b) {return Expr(a) <= std::move(b);}
807 inline Expr operator==(Expr a, float b) {return std::move(a) == Expr(b);}
808 inline Expr operator==(float a, Expr b) {return Expr(a) == std::move(b);}
809 inline Expr operator!=(Expr a, float b) {return std::move(a) != Expr(b);}
810 inline Expr operator!=(float a, Expr b) {return Expr(a) != std::move(b);}
811 // @}
812 
813 /** Clamps an expression to lie within the given bounds. The bounds
814  * are type-cast to match the expression. Vectorizes as well as min/max. */
815 inline Expr clamp(Expr a, Expr min_val, Expr max_val) {
816  user_assert(a.defined() && min_val.defined() && max_val.defined())
817  << "clamp of undefined Expr\n";
818  Expr n_min_val = lossless_cast(a.type(), min_val);
819  user_assert(n_min_val.defined())
820  << "Type mismatch in call to clamp. First argument ("
821  << a << ") has type " << a.type() << ", but second argument ("
822  << min_val << ") has type " << min_val.type() << ". Use an explicit cast.\n";
823  Expr n_max_val = lossless_cast(a.type(), max_val);
824  user_assert(n_max_val.defined())
825  << "Type mismatch in call to clamp. First argument ("
826  << a << ") has type " << a.type() << ", but third argument ("
827  << max_val << ") has type " << max_val.type() << ". Use an explicit cast.\n";
828  return Internal::Max::make(Internal::Min::make(std::move(a), std::move(n_max_val)), std::move(n_min_val));
829 }
830 
831 /** Returns the absolute value of a signed integer or floating-point
832  * expression. Vectorizes cleanly. Unlike in C, abs of a signed
833  * integer returns an unsigned integer of the same bit width. This
834  * means that abs of the most negative integer doesn't overflow. */
835 inline Expr abs(Expr a) {
836  user_assert(a.defined())
837  << "abs of undefined Expr\n";
838  Type t = a.type();
839  if (t.is_uint()) {
840  user_warning << "Warning: abs of an unsigned type is a no-op\n";
841  return a;
842  }
843  return Internal::Call::make(t.with_code(t.is_int() ? Type::UInt : t.code()),
845 }
846 
847 /** Return the absolute difference between two values. Vectorizes
848  * cleanly. Returns an unsigned value of the same bit width. There are
849  * various ways to write this yourself, but they contain numerous
850  * gotchas and don't always compile to good code, so use this
851  * instead. */
852 inline Expr absd(Expr a, Expr b) {
853  user_assert(a.defined() && b.defined()) << "absd of undefined Expr\n";
854  Internal::match_types(a, b);
855  Type t = a.type();
856 
857  if (t.is_float()) {
858  // Floats can just use abs.
859  return abs(std::move(a) - std::move(b));
860  }
861 
862  // The argument may be signed, but the return type is unsigned.
863  return Internal::Call::make(t.with_code(t.is_int() ? Type::UInt : t.code()),
864  Internal::Call::absd, {std::move(a), std::move(b)},
866 }
867 
868 /** Returns an expression similar to the ternary operator in C, except
869  * that it always evaluates all arguments. If the first argument is
870  * true, then return the second, else return the third. Typically
871  * vectorizes cleanly, but benefits from SSE41 or newer on x86. */
872 inline Expr select(Expr condition, Expr true_value, Expr false_value) {
873 
874  if (as_const_int(condition)) {
875  // Why are you doing this? We'll preserve the select node until constant folding for you.
876  condition = cast(Bool(), std::move(condition));
877  }
878 
879  // Coerce int literals to the type of the other argument
880  if (as_const_int(true_value)) {
881  true_value = cast(false_value.type(), std::move(true_value));
882  }
883  if (as_const_int(false_value)) {
884  false_value = cast(true_value.type(), std::move(false_value));
885  }
886 
887  user_assert(condition.type().is_bool())
888  << "The first argument to a select must be a boolean:\n"
889  << " " << condition << " has type " << condition.type() << "\n";
890 
891  user_assert(true_value.type() == false_value.type())
892  << "The second and third arguments to a select do not have a matching type:\n"
893  << " " << true_value << " has type " << true_value.type() << "\n"
894  << " " << false_value << " has type " << false_value.type() << "\n";
895 
896  return Internal::Select::make(std::move(condition), std::move(true_value), std::move(false_value));
897 }
898 
899 /** A multi-way variant of select similar to a switch statement in C,
900  * which can accept multiple conditions and values in pairs. Evaluates
901  * to the first value for which the condition is true. Returns the
902  * final value if all conditions are false. */
903 template<typename... Args,
904  typename std::enable_if<Halide::Internal::all_are_convertible<Expr, Args...>::value>::type* = nullptr>
905 inline Expr select(Expr c0, Expr v0, Expr c1, Expr v1, Args&&... args) {
906  return select(std::move(c0), std::move(v0), select(std::move(c1), std::move(v1), std::forward<Args>(args)...));
907 }
908 
909 // TODO: Implement support for *_f16 external functions in various backends.
910 // No backend supports these yet.
911 
912 /** Return the sine of a floating-point expression. If the argument is
913  * not floating-point, it is cast to Float(32). Does not vectorize
914  * well. */
915 inline Expr sin(Expr x) {
916  user_assert(x.defined()) << "sin of undefined Expr\n";
917  if (x.type() == Float(64)) {
918  return Internal::Call::make(Float(64), "sin_f64", {std::move(x)}, Internal::Call::PureExtern);
919  } else if (x.type() == Float(16)) {
920  return Internal::Call::make(Float(16), "sin_f16", {std::move(x)}, Internal::Call::PureExtern);
921  } else {
922  return Internal::Call::make(Float(32), "sin_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
923  }
924 }
925 
926 /** Return the arcsine of a floating-point expression. If the argument
927  * is not floating-point, it is cast to Float(32). Does not vectorize
928  * well. */
929 inline Expr asin(Expr x) {
930  user_assert(x.defined()) << "asin of undefined Expr\n";
931  if (x.type() == Float(64)) {
932  return Internal::Call::make(Float(64), "asin_f64", {std::move(x)}, Internal::Call::PureExtern);
933  } else if (x.type() == Float(16)) {
934  return Internal::Call::make(Float(16), "asin_f16", {std::move(x)}, Internal::Call::PureExtern);
935  } else {
936  return Internal::Call::make(Float(32), "asin_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
937  }
938 }
939 
940 /** Return the cosine of a floating-point expression. If the argument
941  * is not floating-point, it is cast to Float(32). Does not vectorize
942  * well. */
943 inline Expr cos(Expr x) {
944  user_assert(x.defined()) << "cos of undefined Expr\n";
945  if (x.type() == Float(64)) {
946  return Internal::Call::make(Float(64), "cos_f64", {std::move(x)}, Internal::Call::PureExtern);
947  } else if (x.type() == Float(16)) {
948  return Internal::Call::make(Float(16), "cos_f16", {std::move(x)}, Internal::Call::PureExtern);
949  } else {
950  return Internal::Call::make(Float(32), "cos_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
951  }
952 }
953 
954 /** Return the arccosine of a floating-point expression. If the
955  * argument is not floating-point, it is cast to Float(32). Does not
956  * vectorize well. */
957 inline Expr acos(Expr x) {
958  user_assert(x.defined()) << "acos of undefined Expr\n";
959  if (x.type() == Float(64)) {
960  return Internal::Call::make(Float(64), "acos_f64", {std::move(x)}, Internal::Call::PureExtern);
961  } else if (x.type() == Float(16)) {
962  return Internal::Call::make(Float(16), "acos_f16", {std::move(x)}, Internal::Call::PureExtern);
963  } else {
964  return Internal::Call::make(Float(32), "acos_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
965  }
966 }
967 
968 /** Return the tangent of a floating-point expression. If the argument
969  * is not floating-point, it is cast to Float(32). Does not vectorize
970  * well. */
971 inline Expr tan(Expr x) {
972  user_assert(x.defined()) << "tan of undefined Expr\n";
973  if (x.type() == Float(64)) {
974  return Internal::Call::make(Float(64), "tan_f64", {std::move(x)}, Internal::Call::PureExtern);
975  } else if (x.type() == Float(16)) {
976  return Internal::Call::make(Float(16), "tan_f16", {std::move(x)}, Internal::Call::PureExtern);
977  } else {
978  return Internal::Call::make(Float(32), "tan_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
979  }
980 }
981 
982 /** Return the arctangent of a floating-point expression. If the
983  * argument is not floating-point, it is cast to Float(32). Does not
984  * vectorize well. */
985 inline Expr atan(Expr x) {
986  user_assert(x.defined()) << "atan of undefined Expr\n";
987  if (x.type() == Float(64)) {
988  return Internal::Call::make(Float(64), "atan_f64", {std::move(x)}, Internal::Call::PureExtern);
989  } else if (x.type() == Float(16)) {
990  return Internal::Call::make(Float(16), "atan_f16", {std::move(x)}, Internal::Call::PureExtern);
991  } else {
992  return Internal::Call::make(Float(32), "atan_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
993  }
994 }
995 
996 /** Return the angle of a floating-point gradient. If the argument is
997  * not floating-point, it is cast to Float(32). Does not vectorize
998  * well. */
999 inline Expr atan2(Expr y, Expr x) {
1000  user_assert(x.defined() && y.defined()) << "atan2 of undefined Expr\n";
1001 
1002  if (y.type() == Float(64)) {
1003  x = cast<double>(x);
1004  return Internal::Call::make(Float(64), "atan2_f64", {std::move(y), std::move(x)}, Internal::Call::PureExtern);
1005  } else if (y.type() == Float(16)) {
1006  x = cast<float16_t>(x);
1007  return Internal::Call::make(Float(16), "atan2_f16", {std::move(y), std::move(x)}, Internal::Call::PureExtern);
1008  } else {
1009  y = cast<float>(y);
1010  x = cast<float>(x);
1011  return Internal::Call::make(Float(32), "atan2_f32", {std::move(y), std::move(x)}, Internal::Call::PureExtern);
1012  }
1013 }
1014 
1015 /** Return the hyperbolic sine of a floating-point expression. If the
1016  * argument is not floating-point, it is cast to Float(32). Does not
1017  * vectorize well. */
1018 inline Expr sinh(Expr x) {
1019  user_assert(x.defined()) << "sinh of undefined Expr\n";
1020  if (x.type() == Float(64)) {
1021  return Internal::Call::make(Float(64), "sinh_f64", {std::move(x)}, Internal::Call::PureExtern);
1022  } else if (x.type() == Float(16)) {
1023  return Internal::Call::make(Float(16), "sinh_f16", {std::move(x)}, Internal::Call::PureExtern);
1024  } else {
1025  return Internal::Call::make(Float(32), "sinh_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1026  }
1027 }
1028 
1029 /** Return the hyperbolic arcsinhe of a floating-point expression. If
1030  * the argument is not floating-point, it is cast to Float(32). Does
1031  * not vectorize well. */
1032 inline Expr asinh(Expr x) {
1033  user_assert(x.defined()) << "asinh of undefined Expr\n";
1034  if (x.type() == Float(64)) {
1035  return Internal::Call::make(Float(64), "asinh_f64", {std::move(x)}, Internal::Call::PureExtern);
1036  } else if (x.type() == Float(16)) {
1037  return Internal::Call::make(Float(16), "asinh_f16", {std::move(x)}, Internal::Call::PureExtern);
1038  } else {
1039  return Internal::Call::make(Float(32), "asinh_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1040  }
1041 }
1042 
1043 /** Return the hyperbolic cosine of a floating-point expression. If
1044  * the argument is not floating-point, it is cast to Float(32). Does
1045  * not vectorize well. */
1046 inline Expr cosh(Expr x) {
1047  user_assert(x.defined()) << "cosh of undefined Expr\n";
1048  if (x.type() == Float(64)) {
1049  return Internal::Call::make(Float(64), "cosh_f64", {std::move(x)}, Internal::Call::PureExtern);
1050  } else if (x.type() == Float(16)) {
1051  return Internal::Call::make(Float(16), "cosh_f16", {std::move(x)}, Internal::Call::PureExtern);
1052  } else {
1053  return Internal::Call::make(Float(32), "cosh_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1054  }
1055 }
1056 
1057 /** Return the hyperbolic arccosine of a floating-point expression.
1058  * If the argument is not floating-point, it is cast to
1059  * Float(32). Does not vectorize well. */
1060 inline Expr acosh(Expr x) {
1061  user_assert(x.defined()) << "acosh of undefined Expr\n";
1062  if (x.type() == Float(64)) {
1063  return Internal::Call::make(Float(64), "acosh_f64", {std::move(x)}, Internal::Call::PureExtern);
1064  } else if (x.type() == Float(16)) {
1065  return Internal::Call::make(Float(16), "acosh_f16", {std::move(x)}, Internal::Call::PureExtern);
1066  } else {
1067  return Internal::Call::make(Float(32), "acosh_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1068  }
1069 }
1070 
1071 /** Return the hyperbolic tangent of a floating-point expression. If
1072  * the argument is not floating-point, it is cast to Float(32). Does
1073  * not vectorize well. */
1074 inline Expr tanh(Expr x) {
1075  user_assert(x.defined()) << "tanh of undefined Expr\n";
1076  if (x.type() == Float(64)) {
1077  return Internal::Call::make(Float(64), "tanh_f64", {std::move(x)}, Internal::Call::PureExtern);
1078  } else if (x.type() == Float(16)) {
1079  return Internal::Call::make(Float(16), "tanh_f16", {std::move(x)}, Internal::Call::PureExtern);
1080  } else {
1081  return Internal::Call::make(Float(32), "tanh_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1082  }
1083 }
1084 
1085 /** Return the hyperbolic arctangent of a floating-point expression.
1086  * If the argument is not floating-point, it is cast to
1087  * Float(32). Does not vectorize well. */
1088 inline Expr atanh(Expr x) {
1089  user_assert(x.defined()) << "atanh of undefined Expr\n";
1090  if (x.type() == Float(64)) {
1091  return Internal::Call::make(Float(64), "atanh_f64", {std::move(x)}, Internal::Call::PureExtern);
1092  } else if (x.type() == Float(16)) {
1093  return Internal::Call::make(Float(16), "atanh_f16", {std::move(x)}, Internal::Call::PureExtern);
1094  } else {
1095  return Internal::Call::make(Float(32), "atanh_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1096  }
1097 }
1098 
1099 /** Return the square root of a floating-point expression. If the
1100  * argument is not floating-point, it is cast to Float(32). Typically
1101  * vectorizes cleanly. */
1102 inline Expr sqrt(Expr x) {
1103  user_assert(x.defined()) << "sqrt of undefined Expr\n";
1104  if (x.type() == Float(64)) {
1105  return Internal::Call::make(Float(64), "sqrt_f64", {std::move(x)}, Internal::Call::PureExtern);
1106  } else if (x.type() == Float(16)) {
1107  return Internal::Call::make(Float(16), "sqrt_f16", {std::move(x)}, Internal::Call::PureExtern);
1108  } else {
1109  return Internal::Call::make(Float(32), "sqrt_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1110  }
1111 }
1112 
1113 /** Return the square root of the sum of the squares of two
1114  * floating-point expressions. If the argument is not floating-point,
1115  * it is cast to Float(32). Vectorizes cleanly. */
1116 inline Expr hypot(Expr x, Expr y) {
1117  return sqrt(x * x + y * y);
1118 }
1119 
1120 /** Return the exponential of a floating-point expression. If the
1121  * argument is not floating-point, it is cast to Float(32). For
1122  * Float(64) arguments, this calls the system exp function, and does
1123  * not vectorize well. For Float(32) arguments, this function is
1124  * vectorizable, does the right thing for extremely small or extremely
1125  * large inputs, and is accurate up to the last bit of the
1126  * mantissa. Vectorizes cleanly. */
1127 inline Expr exp(Expr x) {
1128  user_assert(x.defined()) << "exp of undefined Expr\n";
1129  if (x.type() == Float(64)) {
1130  return Internal::Call::make(Float(64), "exp_f64", {std::move(x)}, Internal::Call::PureExtern);
1131  } else if (x.type() == Float(16)) {
1132  return Internal::Call::make(Float(16), "exp_f16", {std::move(x)}, Internal::Call::PureExtern);
1133  } else {
1134  return Internal::Call::make(Float(32), "exp_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1135  }
1136 }
1137 
1138 /** Return the logarithm of a floating-point expression. If the
1139  * argument is not floating-point, it is cast to Float(32). For
1140  * Float(64) arguments, this calls the system log function, and does
1141  * not vectorize well. For Float(32) arguments, this function is
1142  * vectorizable, does the right thing for inputs <= 0 (returns -inf or
1143  * nan), and is accurate up to the last bit of the
1144  * mantissa. Vectorizes cleanly. */
1145 inline Expr log(Expr x) {
1146  user_assert(x.defined()) << "log of undefined Expr\n";
1147  if (x.type() == Float(64)) {
1148  return Internal::Call::make(Float(64), "log_f64", {std::move(x)}, Internal::Call::PureExtern);
1149  } else if (x.type() == Float(16)) {
1150  return Internal::Call::make(Float(16), "log_f16", {std::move(x)}, Internal::Call::PureExtern);
1151  } else {
1152  return Internal::Call::make(Float(32), "log_f32", {cast<float>(std::move(x))}, Internal::Call::PureExtern);
1153  }
1154 }
1155 
1156 /** Return one floating point expression raised to the power of
1157  * another. The type of the result is given by the type of the first
1158  * argument. If the first argument is not a floating-point type, it is
1159  * cast to Float(32). For Float(32), cleanly vectorizable, and
1160  * accurate up to the last few bits of the mantissa. Gets worse when
1161  * approaching overflow. Vectorizes cleanly. */
1162 inline Expr pow(Expr x, Expr y) {
1163  user_assert(x.defined() && y.defined()) << "pow of undefined Expr\n";
1164 
1165  if (const int64_t *i = as_const_int(y)) {
1166  return raise_to_integer_power(std::move(x), *i);
1167  }
1168 
1169  if (x.type() == Float(64)) {
1170  y = cast<double>(std::move(y));
1171  return Internal::Call::make(Float(64), "pow_f64", {std::move(x), std::move(y)}, Internal::Call::PureExtern);
1172  } else if (x.type() == Float(16)) {
1173  y = cast<float16_t>(std::move(y));
1174  return Internal::Call::make(Float(16), "pow_f16", {std::move(x), std::move(y)}, Internal::Call::PureExtern);
1175  } else {
1176  x = cast<float>(std::move(x));
1177  y = cast<float>(std::move(y));
1178  return Internal::Call::make(Float(32), "pow_f32", {std::move(x), std::move(y)}, Internal::Call::PureExtern);
1179  }
1180 }
1181 
1182 /** Evaluate the error function erf. Only available for
1183  * Float(32). Accurate up to the last three bits of the
1184  * mantissa. Vectorizes cleanly. */
1185 inline Expr erf(Expr x) {
1186  user_assert(x.defined()) << "erf of undefined Expr\n";
1187  user_assert(x.type() == Float(32)) << "erf only takes float arguments\n";
1188  return Internal::halide_erf(std::move(x));
1189 }
1190 
1191 /** Fast approximate cleanly vectorizable log for Float(32). Returns
1192  * nonsense for x <= 0.0f. Accurate up to the last 5 bits of the
1193  * mantissa. Vectorizes cleanly. */
1194 EXPORT Expr fast_log(Expr x);
1195 
1196 /** Fast approximate cleanly vectorizable exp for Float(32). Returns
1197  * nonsense for inputs that would overflow or underflow. Typically
1198  * accurate up to the last 5 bits of the mantissa. Gets worse when
1199  * approaching overflow. Vectorizes cleanly. */
1200 EXPORT Expr fast_exp(Expr x);
1201 
1202 /** Fast approximate cleanly vectorizable pow for Float(32). Returns
1203  * nonsense for x < 0.0f. Accurate up to the last 5 bits of the
1204  * mantissa for typical exponents. Gets worse when approaching
1205  * overflow. Vectorizes cleanly. */
1206 inline Expr fast_pow(Expr x, Expr y) {
1207  if (const int64_t *i = as_const_int(y)) {
1208  return raise_to_integer_power(std::move(x), *i);
1209  }
1210 
1211  x = cast<float>(std::move(x));
1212  y = cast<float>(std::move(y));
1213  return select(x == 0.0f, 0.0f, fast_exp(fast_log(x) * std::move(y)));
1214 }
1215 
1216 /** Fast approximate inverse for Float(32). Corresponds to the rcpps
1217  * instruction on x86, and the vrecpe instruction on ARM. Vectorizes
1218  * cleanly. */
1219 inline Expr fast_inverse(Expr x) {
1220  user_assert(x.type() == Float(32)) << "fast_inverse only takes float arguments\n";
1221  Type t = x.type();
1222  return Internal::Call::make(t, "fast_inverse_f32", {std::move(x)}, Internal::Call::PureExtern);
1223 }
1224 
1225 /** Fast approximate inverse square root for Float(32). Corresponds to
1226  * the rsqrtps instruction on x86, and the vrsqrte instruction on
1227  * ARM. Vectorizes cleanly. */
1228 inline Expr fast_inverse_sqrt(Expr x) {
1229  user_assert(x.type() == Float(32)) << "fast_inverse_sqrt only takes float arguments\n";
1230  Type t = x.type();
1231  return Internal::Call::make(t, "fast_inverse_sqrt_f32", {std::move(x)}, Internal::Call::PureExtern);
1232 }
1233 
1234 /** Return the greatest whole number less than or equal to a
1235  * floating-point expression. If the argument is not floating-point,
1236  * it is cast to Float(32). The return value is still in floating
1237  * point, despite being a whole number. Vectorizes cleanly. */
1238 inline Expr floor(Expr x) {
1239  user_assert(x.defined()) << "floor of undefined Expr\n";
1240  Type t = x.type();
1241  if (t.element_of() == Float(64)) {
1242  return Internal::Call::make(t, "floor_f64", {std::move(x)}, Internal::Call::PureExtern);
1243  } else if (t.element_of() == Float(16)) {
1244  return Internal::Call::make(t, "floor_f16", {std::move(x)}, Internal::Call::PureExtern);
1245  } else {
1246  t = t.with_code(Type::Float);
1247  return Internal::Call::make(t, "floor_f32", {cast(t, std::move(x))}, Internal::Call::PureExtern);
1248  }
1249 }
1250 
1251 /** Return the least whole number greater than or equal to a
1252  * floating-point expression. If the argument is not floating-point,
1253  * it is cast to Float(32). The return value is still in floating
1254  * point, despite being a whole number. Vectorizes cleanly. */
1255 inline Expr ceil(Expr x) {
1256  user_assert(x.defined()) << "ceil of undefined Expr\n";
1257  Type t = x.type();
1258  if (t.element_of() == Float(64)) {
1259  return Internal::Call::make(t, "ceil_f64", {std::move(x)}, Internal::Call::PureExtern);
1260  } else if (x.type().element_of() == Float(16)) {
1261  return Internal::Call::make(t, "ceil_f16", {std::move(x)}, Internal::Call::PureExtern);
1262  } else {
1263  t = t.with_code(Type::Float);
1264  return Internal::Call::make(t, "ceil_f32", {cast(t, std::move(x))}, Internal::Call::PureExtern);
1265  }
1266 }
1267 
1268 /** Return the whole number closest to a floating-point expression. If the
1269  * argument is not floating-point, it is cast to Float(32). The return value
1270  * is still in floating point, despite being a whole number. On ties, we
1271  * follow IEEE754 conventions and round to the nearest even number. Vectorizes
1272  * cleanly. */
1273 inline Expr round(Expr x) {
1274  user_assert(x.defined()) << "round of undefined Expr\n";
1275  Type t = x.type();
1276  if (t.element_of() == Float(64)) {
1277  return Internal::Call::make(t, "round_f64", {std::move(x)}, Internal::Call::PureExtern);
1278  } else if (t.element_of() == Float(16)) {
1279  return Internal::Call::make(t, "round_f16", {std::move(x)}, Internal::Call::PureExtern);
1280  } else {
1281  t = t.with_code(Type::Float);
1282  return Internal::Call::make(t, "round_f32", {cast(t, std::move(x))}, Internal::Call::PureExtern);
1283  }
1284 }
1285 
1286 /** Return the integer part of a floating-point expression. If the argument is
1287  * not floating-point, it is cast to Float(32). The return value is still in
1288  * floating point, despite being a whole number. Vectorizes cleanly. */
1289 inline Expr trunc(Expr x) {
1290  user_assert(x.defined()) << "trunc of undefined Expr\n";
1291  Type t = x.type();
1292  if (t.element_of() == Float(64)) {
1293  return Internal::Call::make(t, "trunc_f64", {std::move(x)}, Internal::Call::PureExtern);
1294  } else if (t.element_of() == Float(16)) {
1295  return Internal::Call::make(t, "trunc_f16", {std::move(x)}, Internal::Call::PureExtern);
1296  } else {
1297  t = t.with_code(Type::Float);
1298  return Internal::Call::make(t, "trunc_f32", {cast(t, std::move(x))}, Internal::Call::PureExtern);
1299  }
1300 }
1301 
1302 /** Returns true if the argument is a Not a Number (NaN). Requires a
1303  * floating point argument. Vectorizes cleanly. */
1304 inline Expr is_nan(Expr x) {
1305  user_assert(x.defined()) << "is_nan of undefined Expr\n";
1306  user_assert(x.type().is_float()) << "is_nan only works for float";
1307  Type t = Bool(x.type().lanes());
1308  if (x.type().element_of() == Float(64)) {
1309  return Internal::Call::make(t, "is_nan_f64", {std::move(x)}, Internal::Call::PureExtern);
1310  } else if (x.type().element_of() == Float(64)) {
1311  return Internal::Call::make(t, "is_nan_f16", {std::move(x)}, Internal::Call::PureExtern);
1312  } else {
1313  Type ft = x.type().with_code(Type::Float);
1314  return Internal::Call::make(t, "is_nan_f32", {cast(ft, std::move(x))}, Internal::Call::PureExtern);
1315  }
1316 }
1317 
1318 /** Return the fractional part of a floating-point expression. If the argument
1319  * is not floating-point, it is cast to Float(32). The return value has the
1320  * same sign as the original expression. Vectorizes cleanly. */
1321 inline Expr fract(Expr x) {
1322  user_assert(x.defined()) << "fract of undefined Expr\n";
1323  return x - trunc(x);
1324 }
1325 
1326 /** Reinterpret the bits of one value as another type. */
1327 inline Expr reinterpret(Type t, Expr e) {
1328  user_assert(e.defined()) << "reinterpret of undefined Expr\n";
1329  int from_bits = e.type().bits() * e.type().lanes();
1330  int to_bits = t.bits() * t.lanes();
1331  user_assert(from_bits == to_bits)
1332  << "Reinterpret cast from type " << e.type()
1333  << " which has " << from_bits
1334  << " bits, to type " << t
1335  << " which has " << to_bits << " bits\n";
1337 }
1338 
1339 template<typename T>
1340 inline Expr reinterpret(Expr e) {
1341  return reinterpret(type_of<T>(), e);
1342 }
1343 
1344 /** Return the bitwise and of two expressions (which need not have the
1345  * same type). The type of the result is the type of the first
1346  * argument. */
1347 inline Expr operator&(Expr x, Expr y) {
1348  user_assert(x.defined() && y.defined()) << "bitwise and of undefined Expr\n";
1349  user_assert(x.type().is_int() || x.type().is_uint())
1350  << "The first argument to bitwise and must be an integer or unsigned integer";
1351  user_assert(y.type().is_int() || y.type().is_uint())
1352  << "The second argument to bitwise and must be an integer or unsigned integer";
1353  // First widen or narrow, then bitcast.
1354  if (y.type().bits() != x.type().bits()) {
1355  y = cast(y.type().with_bits(x.type().bits()), y);
1356  }
1357  if (y.type() != x.type()) {
1358  y = reinterpret(x.type(), y);
1359  }
1360  Type t = x.type();
1361  return Internal::Call::make(t, Internal::Call::bitwise_and, {std::move(x), std::move(y)}, Internal::Call::PureIntrinsic);
1362 }
1363 
1364 /** Return the bitwise or of two expressions (which need not have the
1365  * same type). The type of the result is the type of the first
1366  * argument. */
1367 inline Expr operator|(Expr x, Expr y) {
1368  user_assert(x.defined() && y.defined()) << "bitwise or of undefined Expr\n";
1369  user_assert(x.type().is_int() || x.type().is_uint())
1370  << "The first argument to bitwise or must be an integer or unsigned integer";
1371  user_assert(y.type().is_int() || y.type().is_uint())
1372  << "The second argument to bitwise or must be an integer or unsigned integer";
1373  // First widen or narrow, then bitcast.
1374  if (y.type().bits() != x.type().bits()) {
1375  y = cast(y.type().with_bits(x.type().bits()), y);
1376  }
1377  if (y.type() != x.type()) {
1378  y = reinterpret(x.type(), y);
1379  }
1380  Type t = x.type();
1381  return Internal::Call::make(t, Internal::Call::bitwise_or, {std::move(x), std::move(y)}, Internal::Call::PureIntrinsic);
1382 }
1383 
1384 /** Return the bitwise exclusive or of two expressions (which need not
1385  * have the same type). The type of the result is the type of the
1386  * first argument. */
1387 inline Expr operator^(Expr x, Expr y) {
1388  user_assert(x.defined() && y.defined()) << "bitwise xor of undefined Expr\n";
1389  user_assert(x.type().is_int() || x.type().is_uint())
1390  << "The first argument to bitwise xor must be an integer or unsigned integer";
1391  user_assert(y.type().is_int() || y.type().is_uint())
1392  << "The second argument to bitwise xor must be an integer or unsigned integer";
1393  // First widen or narrow, then bitcast.
1394  if (y.type().bits() != x.type().bits()) {
1395  y = cast(y.type().with_bits(x.type().bits()), y);
1396  }
1397  if (y.type() != x.type()) {
1398  y = reinterpret(x.type(), y);
1399  }
1400  Type t = x.type();
1401  return Internal::Call::make(t, Internal::Call::bitwise_xor, {std::move(x), std::move(y)}, Internal::Call::PureIntrinsic);
1402 }
1403 
1404 /** Return the bitwise not of an expression. */
1405 inline Expr operator~(Expr x) {
1406  user_assert(x.defined()) << "bitwise not of undefined Expr\n";
1407  user_assert(x.type().is_int() || x.type().is_uint())
1408  << "Argument to bitwise not must be an integer or unsigned integer";
1409  Type t = x.type();
1411 }
1412 
1413 /** Shift the bits of an integer value left. This is actually less
1414  * efficient than multiplying by 2^n, because Halide's optimization
1415  * passes understand multiplication, and will compile it to
1416  * shifting. This operator is only for if you really really need bit
1417  * shifting (e.g. because the exponent is a run-time parameter). The
1418  * type of the result is equal to the type of the first argument. Both
1419  * arguments must have integer type. */
1420 // @{
1421 inline Expr operator<<(Expr x, Expr y) {
1422  user_assert(x.defined() && y.defined()) << "shift left of undefined Expr\n";
1423  user_assert(!x.type().is_float()) << "First argument to shift left is a float: " << x << "\n";
1424  user_assert(!y.type().is_float()) << "Second argument to shift left is a float: " << y << "\n";
1425  Internal::match_types(x, y);
1426  Type t = x.type();
1427  return Internal::Call::make(t, Internal::Call::shift_left, {std::move(x), std::move(y)}, Internal::Call::PureIntrinsic);
1428 }
1429 inline Expr operator<<(Expr x, int y) {
1430  Type t = x.type();
1432  return std::move(x) << Internal::make_const(t, y);
1433 }
1434 inline Expr operator<<(int x, Expr y) {
1435  Type t = y.type();
1437  return Internal::make_const(t, x) << std::move(y);
1438 }
1439 // @}
1440 
1441 /** Shift the bits of an integer value right. Does sign extension for
1442  * signed integers. This is less efficient than dividing by a power of
1443  * two. Halide's definition of division (always round to negative
1444  * infinity) means that all divisions by powers of two get compiled to
1445  * bit-shifting, and Halide's optimization routines understand
1446  * division and can work with it. The type of the result is equal to
1447  * the type of the first argument. Both arguments must have integer
1448  * type. */
1449 // @{
1450 inline Expr operator>>(Expr x, Expr y) {
1451  user_assert(x.defined() && y.defined()) << "shift right of undefined Expr\n";
1452  user_assert(!x.type().is_float()) << "First argument to shift right is a float: " << x << "\n";
1453  user_assert(!y.type().is_float()) << "Second argument to shift right is a float: " << y << "\n";
1454  Internal::match_types(x, y);
1455  Type t = x.type();
1456  return Internal::Call::make(t, Internal::Call::shift_right, {std::move(x), std::move(y)}, Internal::Call::PureIntrinsic);
1457 }
1458 inline Expr operator>>(Expr x, int y) {
1459  Type t = x.type();
1461  return std::move(x) >> Internal::make_const(t, y);
1462 }
1463 inline Expr operator>>(int x, Expr y) {
1464  Type t = y.type();
1466  return Internal::make_const(t, x) >> std::move(y);
1467 }
1468 // @}
1469 
1470 /** Linear interpolate between the two values according to a weight.
1471  * \param zero_val The result when weight is 0
1472  * \param one_val The result when weight is 1
1473  * \param weight The interpolation amount
1474  *
1475  * Both zero_val and one_val must have the same type. All types are
1476  * supported, including bool.
1477  *
1478  * The weight is treated as its own type and must be float or an
1479  * unsigned integer type. It is scaled to the bit-size of the type of
1480  * x and y if they are integer, or converted to float if they are
1481  * float. Integer weights are converted to float via division by the
1482  * full-range value of the weight's type. Floating-point weights used
1483  * to interpolate between integer values must be between 0.0f and
1484  * 1.0f, and an error may be signaled if it is not provably so. (clamp
1485  * operators can be added to provide proof. Currently an error is only
1486  * signalled for constant weights.)
1487  *
1488  * For integer linear interpolation, out of range values cannot be
1489  * represented. In particular, weights that are conceptually less than
1490  * 0 or greater than 1.0 are not representable. As such the result is
1491  * always between x and y (inclusive of course). For lerp with
1492  * floating-point values and floating-point weight, the full range of
1493  * a float is valid, however underflow and overflow can still occur.
1494  *
1495  * Ordering is not required between zero_val and one_val:
1496  * lerp(42, 69, .5f) == lerp(69, 42, .5f) == 56
1497  *
1498  * Results for integer types are for exactly rounded arithmetic. As
1499  * such, there are cases where 16-bit and float differ because 32-bit
1500  * floating-point (float) does not have enough precision to produce
1501  * the exact result. (Likely true for 32-bit integer
1502  * vs. double-precision floating-point as well.)
1503  *
1504  * At present, double precision and 64-bit integers are not supported.
1505  *
1506  * Generally, lerp will vectorize as if it were an operation on a type
1507  * twice the bit size of the inferred type for x and y.
1508  *
1509  * Some examples:
1510  * \code
1511  *
1512  * // Since Halide does not have direct type delcarations, casts
1513  * // below are used to indicate the types of the parameters.
1514  * // Such casts not required or expected in actual code where types
1515  * // are inferred.
1516  *
1517  * lerp(cast<float>(x), cast<float>(y), cast<float>(w)) ->
1518  * x * (1.0f - w) + y * w
1519  *
1520  * lerp(cast<uint8_t>(x), cast<uint8_t>(y), cast<uint8_t>(w)) ->
1521  * cast<uint8_t>(cast<uint8_t>(x) * (1.0f - cast<uint8_t>(w) / 255.0f) +
1522  * cast<uint8_t>(y) * cast<uint8_t>(w) / 255.0f + .5f)
1523  *
1524  * // Note addition in Halide promoted uint8_t + int8_t to int16_t already,
1525  * // the outer cast is added for clarity.
1526  * lerp(cast<uint8_t>(x), cast<int8_t>(y), cast<uint8_t>(w)) ->
1527  * cast<int16_t>(cast<uint8_t>(x) * (1.0f - cast<uint8_t>(w) / 255.0f) +
1528  * cast<int8_t>(y) * cast<uint8_t>(w) / 255.0f + .5f)
1529  *
1530  * lerp(cast<int8_t>(x), cast<int8_t>(y), cast<float>(w)) ->
1531  * cast<int8_t>(cast<int8_t>(x) * (1.0f - cast<float>(w)) +
1532  * cast<int8_t>(y) * cast<uint8_t>(w))
1533  *
1534  * \endcode
1535  * */
1536 inline Expr lerp(Expr zero_val, Expr one_val, Expr weight) {
1537  user_assert(zero_val.defined()) << "lerp with undefined zero value";
1538  user_assert(one_val.defined()) << "lerp with undefined one value";
1539  user_assert(weight.defined()) << "lerp with undefined weight";
1540 
1541  // We allow integer constants through, so that you can say things
1542  // like lerp(0, cast<uint8_t>(x), alpha) and produce an 8-bit
1543  // result. Note that lerp(0.0f, cast<uint8_t>(x), alpha) will
1544  // produce an error, as will lerp(0.0f, cast<double>(x),
1545  // alpha). lerp(0, cast<float>(x), alpha) is also allowed and will
1546  // produce a float result.
1547  if (as_const_int(zero_val)) {
1548  zero_val = cast(one_val.type(), std::move(zero_val));
1549  }
1550  if (as_const_int(one_val)) {
1551  one_val = cast(zero_val.type(), std::move(one_val));
1552  }
1553 
1554  user_assert(zero_val.type() == one_val.type())
1555  << "Can't lerp between " << zero_val << " of type " << zero_val.type()
1556  << " and " << one_val << " of different type " << one_val.type() << "\n";
1557  user_assert((weight.type().is_uint() || weight.type().is_float()))
1558  << "A lerp weight must be an unsigned integer or a float, but "
1559  << "lerp weight " << weight << " has type " << weight.type() << ".\n";
1560  user_assert((zero_val.type().is_float() || zero_val.type().lanes() <= 32))
1561  << "Lerping between 64-bit integers is not supported\n";
1562  // Compilation error for constant weight that is out of range for integer use
1563  // as this seems like an easy to catch gotcha.
1564  if (!zero_val.type().is_float()) {
1565  const double *const_weight = as_const_float(weight);
1566  if (const_weight) {
1567  user_assert(*const_weight >= 0.0 && *const_weight <= 1.0)
1568  << "Floating-point weight for lerp with integer arguments is "
1569  << *const_weight << ", which is not in the range [0.0, 1.0].\n";
1570  }
1571  }
1572  Type t = zero_val.type();
1574  {std::move(zero_val), std::move(one_val), std::move(weight)},
1576 }
1577 
1578 /** Count the number of set bits in an expression. */
1579 inline Expr popcount(Expr x) {
1580  user_assert(x.defined()) << "popcount of undefined Expr\n";
1581  Type t = x.type();
1582  user_assert(t.is_uint() || t.is_int())
1583  << "Argument to popcount must be an integer\n";
1585  {std::move(x)}, Internal::Call::PureIntrinsic);
1586 }
1587 
1588 /** Count the number of leading zero bits in an expression. The result is
1589  * undefined if the value of the expression is zero. */
1590 inline Expr count_leading_zeros(Expr x) {
1591  user_assert(x.defined()) << "count leading zeros of undefined Expr\n";
1592  Type t = x.type();
1593  user_assert(t.is_uint() || t.is_int())
1594  << "Argument to count_leading_zeros must be an integer\n";
1596  {std::move(x)}, Internal::Call::PureIntrinsic);
1597 }
1598 
1599 /** Count the number of trailing zero bits in an expression. The result is
1600  * undefined if the value of the expression is zero. */
1601 inline Expr count_trailing_zeros(Expr x) {
1602  user_assert(x.defined()) << "count trailing zeros of undefined Expr\n";
1603  Type t = x.type();
1604  user_assert(t.is_uint() || t.is_int())
1605  << "Argument to count_trailing_zeros must be an integer\n";
1607  {std::move(x)}, Internal::Call::PureIntrinsic);
1608 }
1609 
1610 /** Divide two integers, rounding towards zero. This is the typical
1611  * behavior of most hardware architectures, which differs from
1612  * Halide's division operator, which is Euclidean (rounds towards
1613  * -infinity). */
1614 inline Expr div_round_to_zero(Expr x, Expr y) {
1615  user_assert(x.defined()) << "div_round_to_zero of undefined dividend\n";
1616  user_assert(y.defined()) << "div_round_to_zero of undefined divisor\n";
1617  Internal::match_types(x, y);
1618  if (x.type().is_uint()) {
1619  return std::move(x) / std::move(y);
1620  }
1621  user_assert(x.type().is_int()) << "First argument to div_round_to_zero is not an integer: " << x << "\n";
1622  user_assert(y.type().is_int()) << "Second argument to div_round_to_zero is not an integer: " << y << "\n";
1623  Type t = x.type();
1625  {std::move(x), std::move(y)},
1627 }
1628 
1629 /** Compute the remainder of dividing two integers, when division is
1630  * rounding toward zero. This is the typical behavior of most hardware
1631  * architectures, which differs from Halide's mod operator, which is
1632  * Euclidean (produces the remainder when division rounds towards
1633  * -infinity). */
1634 inline Expr mod_round_to_zero(Expr x, Expr y) {
1635  user_assert(x.defined()) << "mod_round_to_zero of undefined dividend\n";
1636  user_assert(y.defined()) << "mod_round_to_zero of undefined divisor\n";
1637  Internal::match_types(x, y);
1638  if (x.type().is_uint()) {
1639  return std::move(x) % std::move(y);
1640  }
1641  user_assert(x.type().is_int()) << "First argument to mod_round_to_zero is not an integer: " << x << "\n";
1642  user_assert(y.type().is_int()) << "Second argument to mod_round_to_zero is not an integer: " << y << "\n";
1643  Type t = x.type();
1645  {std::move(x), std::move(y)},
1647 }
1648 
1649 /** Return a random variable representing a uniformly distributed
1650  * float in the half-open interval [0.0f, 1.0f). For random numbers of
1651  * other types, use lerp with a random float as the last parameter.
1652  *
1653  * Optionally takes a seed.
1654  *
1655  * Note that:
1656  \code
1657  Expr x = random_float();
1658  Expr y = x + x;
1659  \endcode
1660  *
1661  * is very different to
1662  *
1663  \code
1664  Expr y = random_float() + random_float();
1665  \endcode
1666  *
1667  * The first doubles a random variable, and the second adds two
1668  * independent random variables.
1669  *
1670  * A given random variable takes on a unique value that depends
1671  * deterministically on the pure variables of the function they belong
1672  * to, the identity of the function itself, and which definition of
1673  * the function it is used in. They are, however, shared across tuple
1674  * elements.
1675  *
1676  * This function vectorizes cleanly.
1677  */
1678 inline Expr random_float(Expr seed = Expr()) {
1679  // Random floats get even IDs
1680  static std::atomic<int> counter;
1681  int id = (counter++)*2;
1682 
1683  std::vector<Expr> args;
1684  if (seed.defined()) {
1685  user_assert(seed.type() == Int(32))
1686  << "The seed passed to random_float must have type Int(32), but instead is "
1687  << seed << " of type " << seed.type() << "\n";
1688  args.push_back(std::move(seed));
1689  }
1690  args.push_back(id);
1691 
1692  // This is (surprisingly) pure - it's a fixed psuedo-random
1693  // function of its inputs.
1696 }
1697 
1698 /** Return a random variable representing a uniformly distributed
1699  * unsigned 32-bit integer. See \ref random_float. Vectorizes cleanly. */
1700 inline Expr random_uint(Expr seed = Expr()) {
1701  // Random ints get odd IDs
1702  static std::atomic<int> counter;
1703  int id = (counter++)*2 + 1;
1704 
1705  std::vector<Expr> args;
1706  if (seed.defined()) {
1707  user_assert(seed.type() == Int(32) || seed.type() == UInt(32))
1708  << "The seed passed to random_int must have type Int(32) or UInt(32), but instead is "
1709  << seed << " of type " << seed.type() << "\n";
1710  args.push_back(std::move(seed));
1711  }
1712  args.push_back(id);
1713 
1716 }
1717 
1718 /** Return a random variable representing a uniformly distributed
1719  * 32-bit integer. See \ref random_float. Vectorizes cleanly. */
1720 inline Expr random_int(Expr seed = Expr()) {
1721  return cast<int32_t>(random_uint(std::move(seed)));
1722 }
1723 
1724 // Secondary args to print can be Exprs or const char *
1725 namespace Internal {
1726 inline NO_INLINE void collect_print_args(std::vector<Expr> &args) {
1727 }
1728 
1729 template<typename ...Args>
1730 inline NO_INLINE void collect_print_args(std::vector<Expr> &args, const char *arg, Args&&... more_args) {
1731  args.push_back(Expr(std::string(arg)));
1732  collect_print_args(args, std::forward<Args>(more_args)...);
1733 }
1734 
1735 template<typename ...Args>
1736 inline NO_INLINE void collect_print_args(std::vector<Expr> &args, Expr arg, Args&&... more_args) {
1737  args.push_back(std::move(arg));
1738  collect_print_args(args, std::forward<Args>(more_args)...);
1739 }
1740 }
1741 
1742 
1743 /** Create an Expr that prints out its value whenever it is
1744  * evaluated. It also prints out everything else in the arguments
1745  * list, separated by spaces. This can include string literals. */
1746 //@{
1747 EXPORT Expr print(const std::vector<Expr> &values);
1748 
1749 template <typename... Args>
1750 inline NO_INLINE Expr print(Expr a, Args&&... args) {
1751  std::vector<Expr> collected_args = {std::move(a)};
1752  Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
1753  return print(collected_args);
1754 }
1755 //@}
1756 
1757 /** Create an Expr that prints whenever it is evaluated, provided that
1758  * the condition is true. */
1759 // @{
1760 EXPORT Expr print_when(Expr condition, const std::vector<Expr> &values);
1761 
1762 template<typename ...Args>
1763 inline NO_INLINE Expr print_when(Expr condition, Expr a, Args&&... args) {
1764  std::vector<Expr> collected_args = {std::move(a)};
1765  Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
1766  return print_when(std::move(condition), collected_args);
1767 }
1768 
1769 // @}
1770 
1771 /** Create an Expr that that guarantees a precondition.
1772  * If 'condition' is true, the return value is equal to the first Expr.
1773  * If 'condition' is false, halide_error() is called, and the return value
1774  * is arbitrary. Any additional arguments after the first Expr are stringified
1775  * and passed as a user-facing message to halide_error(), similar to print().
1776  *
1777  * Note that this essentially *always* inserts a runtime check into the
1778  * generated code (except when the condition can be proven at compile time);
1779  * as such, it should be avoided inside inner loops, except for debugging
1780  * or testing purposes. Note also that it does not vectorize cleanly (vector
1781  * values will be scalarized for the check).
1782  *
1783  * However, using this to make assertions about (say) input values
1784  * can be useful, both in terms of correctness and (potentially) in terms
1785  * of code generation, e.g.
1786  \code
1787  Param<int> p;
1788  Expr y = require(p > 0, p);
1789  \endcode
1790  * will allow the optimizer to assume positive, nonzero values for y.
1791  */
1792 // @{
1793 EXPORT Expr require(Expr condition, const std::vector<Expr> &values);
1794 
1795 template<typename ...Args>
1796 inline NO_INLINE Expr require(Expr condition, Expr value, Args&&... args) {
1797  std::vector<Expr> collected_args = {std::move(value)};
1798  Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
1799  return require(std::move(condition), collected_args);
1800 }
1801 
1802 // @}
1803 
1804 
1805 /** Return an undef value of the given type. Halide skips stores that
1806  * depend on undef values, so you can use this to mean "do not modify
1807  * this memory location". This is an escape hatch that can be used for
1808  * several things:
1809  *
1810  * You can define a reduction with no pure step, by setting the pure
1811  * step to undef. Do this only if you're confident that the update
1812  * steps are sufficient to correctly fill in the domain.
1813  *
1814  * For a tuple-valued reduction, you can write an update step that
1815  * only updates some tuple elements.
1816  *
1817  * You can define single-stage pipeline that only has update steps,
1818  * and depends on the values already in the output buffer.
1819  *
1820  * Use this feature with great caution, as you can use it to load from
1821  * uninitialized memory.
1822  */
1823 inline Expr undef(Type t) {
1825  std::vector<Expr>(),
1827 }
1828 
1829 template<typename T>
1830 inline Expr undef() {
1831  return undef(type_of<T>());
1832 }
1833 
1834 namespace Internal {
1835 EXPORT Expr memoize_tag_helper(Expr result, const std::vector<Expr> &cache_key_values);
1836 } // namespace Internal
1837 
1838 /** Control the values used in the memoization cache key for memoize.
1839  * Normally parameters and other external dependencies are
1840  * automatically inferred and added to the cache key. The memoize_tag
1841  * operator allows computing one expression and using either the
1842  * computed value, or one or more other expressions in the cache key
1843  * instead of the parameter dependencies of the computation. The
1844  * single argument version is completely safe in that the cache key
1845  * will use the actual computed value -- it is difficult or imposible
1846  * to produce erroneous caching this way. The more-than-one argument
1847  * version allows generating cache keys that do not uniquely identify
1848  * the computation and thus can result in caching errors.
1849  *
1850  * A potential use for the single argument version is to handle a
1851  * floating-point parameter that is quantized to a small
1852  * integer. Mutliple values of the float will produce the same integer
1853  * and moving the caching to using the integer for the key is more
1854  * efficient.
1855  *
1856  * The main use for the more-than-one argument version is to provide
1857  * cache key information for Handles and ImageParams, which otherwise
1858  * are not allowed inside compute_cached operations. E.g. when passing
1859  * a group of parameters to an external array function via a Handle,
1860  * memoize_tag can be used to isolate the actual values used by that
1861  * computation. If an ImageParam is a constant image with a persistent
1862  * digest, memoize_tag can be used to key computations using that image
1863  * on the digest. */
1864 // @{
1865 template<typename ...Args>
1866 inline NO_INLINE Expr memoize_tag(Expr result, Args&&... args) {
1867  std::vector<Expr> collected_args{std::forward<Args>(args)...};
1868  return Internal::memoize_tag_helper(std::move(result), collected_args);
1869 }
1870 // @}
1871 
1872 /** Expressions tagged with this intrinsic are considered to be part
1873  * of the steady state of some loop with a nasty beginning and end
1874  * (e.g. a boundary condition). When Halide encounters likely
1875  * intrinsics, it splits the containing loop body into three, and
1876  * tries to simplify down all conditions that lead to the likely. For
1877  * example, given the expression: select(x < 1, bar, x > 10, bar,
1878  * likely(foo)), Halide will split the loop over x into portions where
1879  * x < 1, 1 <= x <= 10, and x > 10.
1880  *
1881  * You're unlikely to want to call this directly. You probably want to
1882  * use the boundary condition helpers in the BoundaryConditions
1883  * namespace instead.
1884  */
1885 inline Expr likely(Expr e) {
1886  Type t = e.type();
1888  {std::move(e)}, Internal::Call::PureIntrinsic);
1889 }
1890 
1891 /** Equivalent to likely, but only triggers a loop partitioning if
1892  * found in an innermost loop. */
1893 inline Expr likely_if_innermost(Expr e) {
1894  Type t = e.type();
1896  {std::move(e)}, Internal::Call::PureIntrinsic);
1897 }
1898 
1899 
1900 /** Cast an expression to the halide type corresponding to the C++
1901  * type T clamping to the minimum and maximum values of the result
1902  * type. */
1903 template <typename T>
1904 Expr saturating_cast(Expr e) {
1905  return saturating_cast(type_of<T>(), std::move(e));
1906 }
1907 
1908 /** Cast an expression to a new type, clamping to the minimum and
1909  * maximum values of the result type. */
1910 EXPORT Expr saturating_cast(Type t, Expr e);
1911 
1912 }
1913 
1914 #endif
Expr atan(Expr x)
Return the arctangent of a floating-point expression.
Definition: IROperator.h:985
Expr random_uint(Expr seed=Expr())
Return a random variable representing a uniformly distributed unsigned 32-bit integer.
Definition: IROperator.h:1700
Various utility functions used internally Halide.
Expr clamp(Expr a, Expr min_val, Expr max_val)
Clamps an expression to lie within the given bounds.
Definition: IROperator.h:815
static EXPORT ConstString div_round_to_zero
Definition: IR.h:473
static EXPORT Expr make(Expr a, Expr b)
Expr round(Expr x)
Return the whole number closest to a floating-point expression.
Definition: IROperator.h:1273
static EXPORT ConstString popcount
Definition: IR.h:473
bool is_int() const
Is this type a signed integer type?
Definition: Type.h:372
EXPORT Expr const_false(int lanes=1)
Construct the constant boolean false.
A fragment of Halide syntax.
Definition: Expr.h:276
static EXPORT Expr make(Expr value, int lanes)
static const halide_type_code_t Float
Aliases for halide_type_code_t values for legacy compatibility and to match the Halide internal C++ s...
Definition: Type.h:295
decltype((Other) 0||(T) 1) operator||(const Other &a, const GeneratorParam< T > &b)
Logical or between between GeneratorParam<T> and any type that supports operator&& with T...
Definition: Generator.h:926
EXPORT Expr make_zero(Type t)
Construct the representation of zero in the given type.
static EXPORT ConstString undef
Definition: IR.h:473
decltype((Other) 0==(T) 1) operator==(const Other &a, const GeneratorParam< T > &b)
Equality comparison between GeneratorParam<T> and any type that supports operator== with T...
Definition: Generator.h:899
static EXPORT ConstString likely
Definition: IR.h:473
EXPORT bool is_const_power_of_two_integer(const Expr &e, int *bits)
Is the expression a constant integer power of two.
static EXPORT Expr make(Expr a, Expr b)
Expr hypot(Expr x, Expr y)
Return the square root of the sum of the squares of two floating-point expressions.
Definition: IROperator.h:1116
Expr sqrt(Expr x)
Return the square root of a floating-point expression.
Definition: IROperator.h:1102
EXPORT Expr memoize_tag_helper(Expr result, const std::vector< Expr > &cache_key_values)
EXPORT bool is_one(const Expr &e)
Is the expression a const (as defined by is_const), and also equal to one (in all lanes...
decltype((Other) 0<=(T) 1) operator<=(const Other &a, const GeneratorParam< T > &b)
Less than or equal comparison between GeneratorParam<T> and any type that supports operator<= with T...
Definition: Generator.h:890
EXPORT bool is_negative_const(const Expr &e)
Is the expression a const (as defined by is_const), and also strictly less than zero (in all lanes...
A vector with &#39;lanes&#39; elements, in which every element is &#39;value&#39;.
Definition: IR.h:234
Expr count_trailing_zeros(Expr x)
Count the number of trailing zero bits in an expression.
Definition: IROperator.h:1601
Expr mod_round_to_zero(Expr x, Expr y)
Compute the remainder of dividing two integers, when division is rounding toward zero.
Definition: IROperator.h:1634
EXPORT const double * as_const_float(const Expr &e)
If an expression is a FloatImm or a Broadcast of a FloatImm, return a pointer to its value...
Expr undef(Type t)
Return an undef value of the given type.
Definition: IROperator.h:1823
Expr sin(Expr x)
Return the sine of a floating-point expression.
Definition: IROperator.h:915
bool is_uint() const
Is this type an unsigned integer type?
Definition: Type.h:375
static EXPORT Expr make(Expr a, Expr b)
Expr fast_pow(Expr x, Expr y)
Fast approximate cleanly vectorizable pow for Float(32).
Definition: IROperator.h:1206
bool is_handle() const
Is this type an opaque handle type (void *)
Definition: Type.h:378
EXPORT Expr fast_exp(Expr x)
Fast approximate cleanly vectorizable exp for Float(32).
EXPORT bool is_zero(const Expr &e)
Is the expression a const (as defined by is_const), and also equal to zero (in all lanes...
Expr acosh(Expr x)
Return the hyperbolic arccosine of a floating-point expression.
Definition: IROperator.h:1060
signed __INT8_TYPE__ int8_t
EXPORT Expr halide_log(Expr a)
Halide&#39;s vectorizable transcendentals.
static EXPORT ConstString shift_right
Definition: IR.h:473
bool is_vector() const
Is this type a vector type? (lanes() != 1).
Definition: Type.h:362
EXPORT bool is_no_op(const Stmt &s)
Is the statement a no-op (which we represent as either an undefined Stmt, or as an Evaluate node of a...
EXPORT bool is_undef(const Expr &e)
Is the expression an undef.
static EXPORT Expr make(Expr a, Expr b)
EXPORT Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
Expr div_round_to_zero(Expr x, Expr y)
Divide two integers, rounding towards zero.
Definition: IROperator.h:1614
Expr cast(Expr a)
Cast an expression to the halide type corresponding to the C++ type T.
Definition: IROperator.h:205
Expr strided_ramp_base(Expr e, int stride=1)
If e is a ramp expression with stride, default 1, return the base, otherwise undefined.
NO_INLINE void collect_print_args(std::vector< Expr > &args)
Definition: IROperator.h:1726
Defines methods for manipulating and analyzing boolean expressions.
EXPORT Expr print_when(Expr condition, const std::vector< Expr > &values)
Create an Expr that prints whenever it is evaluated, provided that the condition is true...
static EXPORT Expr make(Expr a)
static EXPORT Expr make(Expr a, Expr b)
decltype((Other) 0+(T) 0) operator+(const Other &a, const GeneratorParam< T > &b)
Addition between GeneratorParam<T> and any type that supports operator+ with T.
Definition: Generator.h:818
Type element_of() const
Produce the scalar type (that of a single element) of this vector type.
Definition: Type.h:404
EXPORT Expr make_bool(bool val, int lanes=1)
Construct a boolean constant from a C++ boolean value.
Expr & operator+=(Expr &a, Expr b)
Modify the first expression to be the sum of two expressions, without changing its type...
Definition: IROperator.h:280
unsigned __INT8_TYPE__ uint8_t
Expr tan(Expr x)
Return the tangent of a floating-point expression.
Definition: IROperator.h:971
Expr & operator*=(Expr &a, Expr b)
Modify the first expression to be the product of two expressions, without changing its type...
Definition: IROperator.h:367
static EXPORT ConstString absd
Definition: IR.h:473
Type with_code(halide_type_code_t new_code) const
Return Type with same number of bits and lanes, but new_code for a type code.
Definition: Type.h:337
Expr select(Expr condition, Expr true_value, Expr false_value)
Returns an expression similar to the ternary operator in C, except that it always evaluates all argum...
Definition: IROperator.h:872
Expr acos(Expr x)
Return the arccosine of a floating-point expression.
Definition: IROperator.h:957
Expr min(FuncRef a, FuncRef b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:418
decltype((Other) 0 -(T) 0) operator-(const Other &a, const GeneratorParam< T > &b)
Subtraction between GeneratorParam<T> and any type that supports operator- with T.
Definition: Generator.h:827
Expr atan2(Expr y, Expr x)
Return the angle of a floating-point gradient.
Definition: IROperator.h:999
EXPORT bool is_const(const Expr &e)
Is the expression either an IntImm, a FloatImm, a StringImm, or a Cast of the same, or a Ramp or Broadcast of the same.
Expr absd(Expr a, Expr b)
Return the absolute difference between two values.
Definition: IROperator.h:852
std::vector< Expr > strides
Definition: IROperator.h:192
static EXPORT ConstString bitwise_not
Definition: IR.h:473
static EXPORT Expr make(Expr a, Expr b)
Type with_bits(int new_bits) const
Return Type with same type code and lanes, but new_bits for the number of bits.
Definition: Type.h:343
Expr floor(Expr x)
Return the greatest whole number less than or equal to a floating-point expression.
Definition: IROperator.h:1238
static EXPORT ConstString mod_round_to_zero
Definition: IR.h:473
Expr ceil(Expr x)
Return the least whole number greater than or equal to a floating-point expression.
Definition: IROperator.h:1255
bool is_bool() const
Is this type boolean (represented as UInt(1))?
Definition: Type.h:358
decltype((Other) 0<(T) 1) operator<(const Other &a, const GeneratorParam< T > &b)
Less than comparison between GeneratorParam<T> and any type that supports operator< with T...
Definition: Generator.h:872
Expr random_float(const std::vector< Expr > &)
Return a random floating-point number between zero and one that varies deterministically based on the...
halide_type_code_t code() const
Return the underlying data type of an element as an enum value.
Definition: Type.h:328
EXPORT Expr const_true(int lanes=1)
Construct the constant boolean true.
EXPORT Expr lossless_cast(Type t, Expr e)
Attempt to cast an expression to a smaller type while provably not losing information.
Expr operator|(Expr x, Expr y)
Return the bitwise or of two expressions (which need not have the same type).
Definition: IROperator.h:1367
static EXPORT Expr make(Expr a, Expr b)
Expr abs(Expr a)
Returns the absolute value of a signed integer or floating-point expression.
Definition: IROperator.h:835
static EXPORT Expr make(Expr a, Expr b)
A side-effect-free version of the above.
Definition: IR.h:462
decltype((Other) 0 !=(T) 1) operator!=(const Other &a, const GeneratorParam< T > &b)
Inequality comparison between between GeneratorParam<T> and any type that supports operator!= with T...
Definition: Generator.h:908
#define NO_INLINE
Definition: Util.h:41
Expr erf(Expr x)
Evaluate the error function erf.
Definition: IROperator.h:1185
Class that provides a type that implements half precision floating point (IEEE754 2008 binary16) in s...
Definition: Float16.h:17
Expr pow(Expr x, Expr y)
Return one floating point expression raised to the power of another.
Definition: IROperator.h:1162
Expr cos(Expr x)
Return the cosine of a floating-point expression.
Definition: IROperator.h:943
Expr & operator-=(Expr &a, Expr b)
Modify the first expression to be the difference of two expressions, without changing its type...
Definition: IROperator.h:329
Expr trunc(Expr x)
Return the integer part of a floating-point expression.
Definition: IROperator.h:1289
bool is_float() const
Is this type a floating point type (float or double).
Definition: Type.h:369
Expr cosh(Expr x)
Return the hyperbolic cosine of a floating-point expression.
Definition: IROperator.h:1046
Expr fast_inverse(Expr x)
Fast approximate inverse for Float(32).
Definition: IROperator.h:1219
EXPORT bool is_negative_negatable_const(const Expr &e)
Is the expression a const (as defined by is_const), and also strictly less than zero (in all lanes...
static EXPORT ConstString bitwise_and
Definition: IR.h:473
A call to a guaranteed-side-effect-free external function.
Definition: IR.h:459
static EXPORT Expr make(Expr a, Expr b)
static EXPORT ConstString bitwise_xor
Definition: IR.h:473
Expr fract(Expr x)
Return the fractional part of a floating-point expression.
Definition: IROperator.h:1321
static EXPORT ConstString count_leading_zeros
Definition: IR.h:473
static EXPORT Expr make(Expr a, Expr b)
A builder to help create Exprs representing halide_buffer_t structs (e.g.
Definition: IROperator.h:187
EXPORT Expr make_one(Type t)
Construct the representation of one in the given type.
EXPORT void match_types(Expr &a, Expr &b)
Coerce the two expressions to have the same type, using C-style casting rules.
#define internal_assert(c)
Definition: Error.h:140
const T * as() const
Downcast this ir node to its actual type (e.g.
Definition: Expr.h:172
EXPORT Expr make_two(Type t)
Construct the representation of two in the given type.
EXPORT Expr require(Expr condition, const std::vector< Expr > &values)
Create an Expr that that guarantees a precondition.
static const halide_type_code_t UInt
Aliases for halide_type_code_t values for legacy compatibility and to match the Halide internal C++ s...
Definition: Type.h:294
Expr sinh(Expr x)
Return the hyperbolic sine of a floating-point expression.
Definition: IROperator.h:1018
static EXPORT Expr make(Expr a, Expr b)
static EXPORT Expr make(Expr a, Expr b)
Expr log(Expr x)
Return the logarithm of a floating-point expression.
Definition: IROperator.h:1145
unsigned __INT32_TYPE__ uint32_t
Type type() const
Get the type of this expression node.
Definition: Expr.h:302
Expr asin(Expr x)
Return the arcsine of a floating-point expression.
Definition: IROperator.h:929
Expr atanh(Expr x)
Return the hyperbolic arctangent of a floating-point expression.
Definition: IROperator.h:1088
Expr operator^(Expr x, Expr y)
Return the bitwise exclusive or of two expressions (which need not have the same type).
Definition: IROperator.h:1387
#define user_error
Definition: Error.h:136
Expr reinterpret(Type t, Expr e)
Reinterpret the bits of one value as another type.
Definition: IROperator.h:1327
No name mangling.
signed __INT64_TYPE__ int64_t
static EXPORT ConstString count_trailing_zeros
Definition: IR.h:473
Type Bool(int lanes=1)
Construct a boolean type.
Definition: Type.h:452
static EXPORT ConstString bitwise_or
Definition: IR.h:473
static EXPORT Expr make(Type type, const std::string &name, const std::vector< Expr > &args, CallType call_type, FunctionPtr func=FunctionPtr(), int value_index=0, Buffer<> image=Buffer<>(), Parameter param=Parameter())
Expr fast_inverse_sqrt(Expr x)
Fast approximate inverse square root for Float(32).
Definition: IROperator.h:1228
static EXPORT ConstString random
Definition: IR.h:473
static EXPORT ConstString abs
Definition: IR.h:473
decltype((Other) 0 >=(T) 1) operator>=(const Other &a, const GeneratorParam< T > &b)
Greater than or equal comparison between GeneratorParam<T> and any type that supports operator>= with...
Definition: Generator.h:881
Subtypes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt) ...
EXPORT bool is_positive_const(const Expr &e)
Is the expression a const (as defined by is_const), and also strictly greater than zero (in all lanes...
decltype((Other) 0 *(T) 0) operator*(const Other &a, const GeneratorParam< T > &b)
Multiplication between GeneratorParam<T> and any type that supports operator* with T...
Definition: Generator.h:836
Type UInt(int bits, int lanes=1)
Constructing an unsigned integer type.
Definition: Type.h:442
#define user_assert(c)
Definition: Error.h:141
EXPORT Expr halide_exp(Expr a)
Halide&#39;s vectorizable transcendentals.
Expr tanh(Expr x)
Return the hyperbolic tangent of a floating-point expression.
Definition: IROperator.h:1074
bool is_scalar() const
Is this type a scalar type? (lanes() == 1).
Definition: Type.h:366
static EXPORT ConstString reinterpret
Definition: IR.h:473
unsigned __INT16_TYPE__ uint16_t
Types in the halide type system.
Definition: Type.h:285
EXPORT const int64_t * as_const_int(const Expr &e)
If an expression is an IntImm or a Broadcast of an IntImm, return a pointer to its value...
Expr operator>>(Expr x, Expr y)
Shift the bits of an integer value right.
Definition: IROperator.h:1450
static EXPORT Expr make(Expr a, Expr b)
Expr is_nan(Expr x)
Returns true if the argument is a Not a Number (NaN).
Definition: IROperator.h:1304
decltype((Other) 0 &&(T) 1) operator &&(const Other &a, const GeneratorParam< T > &b)
Logical and between between GeneratorParam<T> and any type that supports operator&& with T...
Definition: Generator.h:917
EXPORT void check_representable(Type t, int64_t val)
Check if a constant value can be correctly represented as the given type.
static EXPORT ConstString lerp
Definition: IR.h:473
Expr & operator/=(Expr &a, Expr b)
Modify the first expression to be the ratio of two expressions, without changing its type...
Definition: IROperator.h:389
decltype((Other) 0 >(T) 1) operator>(const Other &a, const GeneratorParam< T > &b)
Greater than comparison between GeneratorParam<T> and any type that supports operator> with T...
Definition: Generator.h:863
Expr likely_if_innermost(Expr e)
Equivalent to likely, but only triggers a loop partitioning if found in an innermost loop...
Definition: IROperator.h:1893
Expr operator &(Expr x, Expr y)
Return the bitwise and of two expressions (which need not have the same type).
Definition: IROperator.h:1347
int bits() const
Return the bit size of a single element of this type.
Definition: Type.h:331
decltype((Other) 0 %(T) 1) operator%(const Other &a, const GeneratorParam< T > &b)
Modulo between GeneratorParam<T> and any type that supports operator% with T.
Definition: Generator.h:854
Expr operator~(Expr x)
Return the bitwise not of an expression.
Definition: IROperator.h:1405
std::vector< Expr > mins
Definition: IROperator.h:192
NO_INLINE Expr memoize_tag(Expr result, Args &&... args)
Control the values used in the memoization cache key for memoize.
Definition: IROperator.h:1866
#define EXPORT
Definition: Util.h:30
Expr lerp(Expr zero_val, Expr one_val, Expr weight)
Linear interpolate between the two values according to a weight.
Definition: IROperator.h:1536
Expr exp(Expr x)
Return the exponential of a floating-point expression.
Definition: IROperator.h:1127
static EXPORT Expr make(Expr a, Expr b)
EXPORT const uint64_t * as_const_uint(const Expr &e)
If an expression is a UIntImm or a Broadcast of a UIntImm, return a pointer to its value...
static EXPORT Expr make(Expr a, Expr b)
EXPORT bool is_two(const Expr &e)
Is the expression a const (as defined by is_const), and also equal to two (in all lanes...
EXPORT void split_into_ands(const Expr &cond, std::vector< Expr > &result)
Split a boolean condition into vector of ANDs.
unsigned __INT64_TYPE__ uint64_t
Expr random_int(const std::vector< Expr > &)
Return a random unsigned integer between zero and 2^32-1 that varies deterministically based on the i...
EXPORT Expr raise_to_integer_power(Expr a, int64_t b)
Raise an expression to an integer power by repeatedly multiplying it by itself.
decltype((Other) 0/(T) 1) operator/(const Other &a, const GeneratorParam< T > &b)
Division between GeneratorParam<T> and any type that supports operator/ with T.
Definition: Generator.h:845
int lanes() const
Return the number of vector elements in this type.
Definition: Type.h:334
#define user_warning
Definition: Error.h:137
static EXPORT ConstString likely_if_innermost
Definition: IR.h:473
static EXPORT Expr make(Expr condition, Expr true_value, Expr false_value)
decltype(!(T) 0) operator!(const GeneratorParam< T > &a)
Not operator for GeneratorParam.
Definition: Generator.h:980
static EXPORT ConstString shift_left
Definition: IR.h:473
Expr likely(Expr e)
Expressions tagged with this intrinsic are considered to be part of the steady state of some loop wit...
Definition: IROperator.h:1885
Expr max(FuncRef a, FuncRef b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:419
EXPORT Expr halide_erf(Expr a)
Halide&#39;s vectorizable transcendentals.
Expr asinh(Expr x)
Return the hyperbolic arcsinhe of a floating-point expression.
Definition: IROperator.h:1032
signed __INT32_TYPE__ int32_t
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
Definition: Type.h:437
std::vector< Expr > extents
Definition: IROperator.h:192
signed __INT16_TYPE__ int16_t
bool is_pure(const Expr &e)
Does the expression 1) Take on the same value no matter where it appears in a Stmt, and 2) Evaluating it has no side-effects.
Expr saturating_cast(Expr e)
Cast an expression to the halide type corresponding to the C++ type T clamping to the minimum and max...
Definition: IROperator.h:1904
EXPORT Expr fast_log(Expr x)
Fast approximate cleanly vectorizable log for Float(32).
static EXPORT Expr make(Type t, Expr v)
Expr count_leading_zeros(Expr x)
Count the number of leading zero bits in an expression.
Definition: IROperator.h:1590
EXPORT Expr make_const(Type t, int64_t val)
Construct an immediate of the given type from any numeric C++ type.
Type Float(int bits, int lanes=1)
Construct a floating-point type.
Definition: Type.h:447
EXPORT std::ostream & operator<<(std::ostream &stream, const Stmt &)
Emit a halide statement on an output stream (such as std::cout) in a human-readable form...
Expr popcount(Expr x)
Count the number of set bits in an expression.
Definition: IROperator.h:1579