Halide 22.0.0 Halide compiler and libraries

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 <cmath>
11#include <map>
12#include <optional>
13
14#include "ConstantInterval.h"
15#include "Expr.h"
16#include "Scope.h"
17#include "Target.h"
18#include "Tuple.h"
19
20 namespace Halide {
21
22 namespace Internal {
23/** Is the expression either an IntImm, a FloatImm, a StringImm, or a
24 * Cast of the same, or a Ramp or Broadcast of the same. Doesn't do
25 * any constant folding. */
26 bool is_const(const Expr &e);
27
28/** Is the expression an IntImm, FloatImm of a particular value, or a
29 * Cast, or Broadcast of the same. */
30 bool is_const(const Expr &e, int64_t v);
31
32/** If an expression is an IntImm or a Broadcast of an IntImm, return
33 * a its value. Otherwise returns std::nullopt. */
34std::optional<int64_t> as_const_int(const Expr &e);
35
36/** If an expression is a UIntImm or a Broadcast of a UIntImm, return
37 * its value. Otherwise returns std::nullopt. */
38std::optional<uint64_t> as_const_uint(const Expr &e);
39
40/** If an expression is a FloatImm or a Broadcast of a FloatImm,
41 * return its value. Otherwise returns std::nullopt. */
42std::optional<double> as_const_float(const Expr &e);
43
44/** Is the expression a constant integer power of two. Returns log base two of
45 * the expression if it is, or std::nullopt if not. Also returns std::nullopt
46 * for non-integer types. */
47// @{
48std::optional<int> is_const_power_of_two_integer(const Expr &e);
49std::optional<int> is_const_power_of_two_integer(uint64_t);
50std::optional<int> is_const_power_of_two_integer(int64_t);
51// @}
52
53/** Is the expression a const (as defined by is_const), and also
54 * strictly greater than zero (in all lanes, if a vector expression) */
55 bool is_positive_const(const Expr &e);
56
57/** Is the expression a const (as defined by is_const), and also
58 * strictly less than zero (in all lanes, if a vector expression) */
59 bool is_negative_const(const Expr &e);
60
61/** Is the expression an undef */
62 bool is_undef(const Expr &e);
63
64/** Is the expression a const (as defined by is_const), and also equal
65 * to zero (in all lanes, if a vector expression) */
66 bool is_const_zero(const Expr &e);
67
68/** Is the expression a const (as defined by is_const), and also equal
69 * to one (in all lanes, if a vector expression) */
70 bool is_const_one(const Expr &e);
71
72/** Is the statement a no-op (which we represent as either an
73 * undefined Stmt, or as an Evaluate node of a constant) */
74 bool is_no_op(const Stmt &s);
75
76/** Does the expression
77 * 1) Take on the same value no matter where it appears in a Stmt, and
78 * 2) Evaluating it has no side-effects
79 */
80 bool is_pure(const Expr &e);
81
82/** Construct an immediate of the given type from any numeric C++ type. */
83// @{
84 Expr make_const(Type t, int64_t val);
85 Expr make_const(Type t, uint64_t val);
86 Expr make_const(Type t, double val);
87 inline Expr make_const(Type t, int32_t val) {
88 return make_const(t, (int64_t)val);
89}
90 inline Expr make_const(Type t, uint32_t val) {
91 return make_const(t, (uint64_t)val);
92}
93 inline Expr make_const(Type t, int16_t val) {
94 return make_const(t, (int64_t)val);
95}
96 inline Expr make_const(Type t, uint16_t val) {
97 return make_const(t, (uint64_t)val);
98}
99 inline Expr make_const(Type t, int8_t val) {
100 return make_const(t, (int64_t)val);
101}
102 inline Expr make_const(Type t, uint8_t val) {
103 return make_const(t, (uint64_t)val);
104}
105 inline Expr make_const(Type t, bool val) {
106 return make_const(t, (uint64_t)val);
107}
108 inline Expr make_const(Type t, float val) {
109 return make_const(t, (double)val);
110}
111 inline Expr make_const(Type t, float16_t val) {
112 return make_const(t, (double)val);
113}
114// @}
115
116/** Construct a unique signed_integer_overflow Expr */
117 Expr make_signed_integer_overflow(Type type);
118
119/** Check if an expression is a signed_integer_overflow */
120 bool is_signed_integer_overflow(const Expr &expr);
121
122/** Check if a constant value can be correctly represented as the given type. */
123 void check_representable(Type t, int64_t val);
124
125/** Construct a boolean constant from a C++ boolean value.
126 * May also be a vector if width is given.
127 * It is not possible to coerce a C++ boolean to Expr because
128 * if we provide such a path then char objects can ambiguously
129 * be converted to Halide Expr or to std::string. The problem
130 * is that C++ does not have a real bool type - it is in fact
131 * close enough to char that C++ does not know how to distinguish them.
132 * make_bool is the explicit coercion. */
133 Expr make_bool(bool val, int lanes = 1);
134
135/** Construct the representation of zero in the given type */
136 Expr make_zero(Type t);
137
138/** Construct the representation of one in the given type */
139 Expr make_one(Type t);
140
141/** Construct the representation of two in the given type */
142 Expr make_two(Type t);
143
144/** Construct the constant boolean true. May also be a vector of
145 * trues, if a lanes argument is given. */
146 Expr const_true(int lanes = 1);
147
148/** Construct the constant boolean false. May also be a vector of
149 * falses, if a lanes argument is given. */
150 Expr const_false(int lanes = 1);
151
152/** Attempt to cast an expression to a smaller type while provably not losing
153 * information. If it can't be done, return an undefined Expr.
154 *
155 * Optionally accepts a scope giving the constant bounds of any variables, and a
156 * map that gives the constant bounds of exprs already analyzed to avoid redoing
157 * work across many calls to lossless_cast. It is not safe to use this optional
158 * map in contexts where the same Expr object may take on a different value. For
159 * example: (let x = 4 in some_expr_object) + (let x = 5 in
160 * the_same_expr_object)). It is safe to use it after uniquify_variable_names
161 * has been run. */
162 Expr lossless_cast(Type t, Expr e,
163 const Scope<ConstantInterval> &scope = Scope<ConstantInterval>::empty_scope(),
164 std::map<Expr, ConstantInterval, ExprCompare> *cache = nullptr);
165
166/** Attempt to negate x without introducing new IR and without overflow.
167 * If it can't be done, return an undefined Expr. */
168 Expr lossless_negate(const Expr &x);
169
170/** Coerce the two expressions to have the same type, using C-style
171 * casting rules. For the purposes of casting, a boolean type is
172 * UInt(1). We use the following procedure:
173 *
174 * If the types already match, do nothing.
175 *
176 * Then, if one type is a vector and the other is a scalar, the scalar
177 * is broadcast to match the vector width, and we continue.
178 *
179 * Then, if one type is floating-point and the other is not, the
180 * non-float is cast to the floating-point type, and we're done.
181 *
182 * Then, if both types are unsigned ints, the one with fewer bits is
183 * cast to match the one with more bits and we're done.
184 *
185 * Then, if both types are signed ints, the one with fewer bits is
186 * cast to match the one with more bits and we're done.
187 *
188 * Finally, if one type is an unsigned int and the other type is a signed
189 * int, both are cast to a signed int with the greater of the two
190 * bit-widths. For example, matching an Int(8) with a UInt(16) results
191 * in an Int(16).
192 *
193 */
194 void match_types(Expr &a, Expr &b);
195
196/** Asserts that both expressions are integer types and are either
197 * both signed or both unsigned. If one argument is scalar and the
198 * other a vector, the scalar is broadcasted to have the same number
199 * of lanes as the vector. If one expression is of narrower type than
200 * the other, it is widened to the bit width of the wider. */
201 void match_types_bitwise(Expr &a, Expr &b, const char *op_name);
202
203/** Halide's vectorizable transcendentals. */
204// @{
205 Expr halide_log(const Expr &a);
206 Expr halide_exp(const Expr &a);
207 Expr halide_erf(const Expr &a);
208// @}
209
210/** Raise an expression to an integer power by repeatedly multiplying
211 * it by itself. */
212 Expr raise_to_integer_power(Expr a, int64_t b);
213
214/** Split a boolean condition into vector of ANDs. If 'cond' is undefined,
215 * return an empty vector. */
216 void split_into_ands(const Expr &cond, std::vector<Expr> &result);
217
218/** A builder to help create Exprs representing halide_buffer_t
219 * structs (e.g. foo.buffer) via calls to halide_buffer_init. Fill out
220 * the fields and then call build. The resulting Expr will be a call
221 * to halide_buffer_init with the struct members as arguments. If the
222 * buffer_memory field is undefined, it uses a call to alloca to make
223 * some stack memory for the buffer. If the shape_memory field is
224 * undefined, it similarly uses stack memory for the shape. If the
225 * shape_memory field is null, it uses the dim field already in the
226 * buffer. Other unitialized fields will take on a value of zero in
227 * the constructed buffer. */
228 struct BufferBuilder {
229 Expr buffer_memory, shape_memory;
230 Expr host, device, device_interface;
231 Type type;
232 int dimensions = 0;
233 std::vector<Expr> mins, extents, strides;
234 Expr host_dirty, device_dirty;
235 Expr build() const;
236};
237
238/** If e is a ramp expression with stride, default 1, return the base,
239 * otherwise undefined. */
240 Expr strided_ramp_base(const Expr &e, int stride = 1);
241
242/** Implementations of division and mod that are specific to Halide.
243 * Use these implementations; do not use native C division or mod to
244 * simplify Halide expressions. Halide division and modulo satisify
245 * the Euclidean definition of division for integers a and b:
246 *
247 /code
248 when b != 0, (a/b)*b + a%b = a
249 0 <= a%b < |b|
250 /endcode
251 *
252 * Additionally, mod by zero returns zero, and div by zero returns
253 * zero. This makes mod and div total functions.
254 */
255// @{
256 template<typename T>
257 inline T mod_imp(T a, T b) {
258 Type t = type_of<T>();
259 if (!t.is_float() && b == 0) {
260 return 0;
261 } else if (t.is_int()) {
262 int64_t ia = a;
263 int64_t ib = b;
264 int64_t a_neg = ia >> 63;
265 int64_t b_neg = ib >> 63;
266 int64_t b_zero = (ib == 0) ? -1 : 0;
267 ia -= a_neg;
268 int64_t r = ia % (ib | b_zero);
269 r += (a_neg & ((ib ^ b_neg) + ~b_neg));
270 r &= ~b_zero;
271 return r;
272 } else {
273 return a % b;
274 }
275}
276
277 template<typename T>
278 inline T div_imp(T a, T b) {
279 Type t = type_of<T>();
280 if (!t.is_float() && b == 0) {
281 return (T)0;
282 } else if (t.is_int()) {
283 // Do it as 64-bit
284 int64_t ia = a;
285 int64_t ib = b;
286 int64_t a_neg = ia >> 63;
287 int64_t b_neg = ib >> 63;
288 int64_t b_zero = (ib == 0) ? -1 : 0;
289 ib -= b_zero;
290 ia -= a_neg;
291 int64_t q = ia / ib;
292 q += a_neg & (~b_neg - b_neg);
293 q &= ~b_zero;
294 return (T)q;
295 } else {
296 return a / b;
297 }
298}
299// @}
300
301// Special cases for float, double.
302 template<>
303 inline float mod_imp<float>(float a, float b) {
304 float f = a - b * (floorf(a / b));
305 // The remainder has the same sign as b.
306 return f;
307}
308 template<>
309 inline double mod_imp<double>(double a, double b) {
310 double f = a - b * (std::floor(a / b));
311 return f;
312}
313
314 template<>
315 inline float div_imp<float>(float a, float b) {
316 return a / b;
317}
318 template<>
319 inline double div_imp<double>(double a, double b) {
320 return a / b;
321}
322
323/** Return an Expr that is identical to the input Expr, but with
324 * all calls to likely() and likely_if_innermost() removed. */
325 Expr remove_likelies(const Expr &e);
326
327/** Return a Stmt that is identical to the input Stmt, but with
328 * all calls to likely() and likely_if_innermost() removed. */
329 Stmt remove_likelies(const Stmt &s);
330
331/** Return an Expr that is identical to the input Expr, but with
332 * all calls to promise_clamped() and unsafe_promise_clamped() removed. */
333 Expr remove_promises(const Expr &e);
334
335/** Return a Stmt that is identical to the input Stmt, but with
336 * all calls to promise_clamped() and unsafe_promise_clamped() removed. */
337 Stmt remove_promises(const Stmt &s);
338
339/** If the expression is a tag helper call, remove it and return
340 * the tagged expression. If not, returns the expression. */
341 Expr unwrap_tags(const Expr &e);
342
343 template<typename T>
344 struct is_printable_arg {
345 static constexpr bool value = std::is_convertible_v<T, const char *> ||
346 std::is_convertible_v<T, Halide::Expr>;
347};
348
349 template<typename... Args>
350 struct all_are_printable_args : meta_and<is_printable_arg<Args>...> {};
351
352 template<typename... Args>
353 inline constexpr bool all_are_printable_args_v = all_are_printable_args<Args...>::value;
354
355// Secondary args to print can be Exprs or const char *
356 inline HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector<Expr> &args) {
357}
358
359 template<typename... Args>
360 inline HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector<Expr> &args, const char *arg, Args &&...more_args) {
361 args.emplace_back(std::string(arg));
362 collect_print_args(args, std::forward<Args>(more_args)...);
363}
364
365 template<typename... Args>
366 inline HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector<Expr> &args, Expr arg, Args &&...more_args) {
367 args.push_back(std::move(arg));
368 collect_print_args(args, std::forward<Args>(more_args)...);
369}
370
371 Expr requirement_failed_error(Expr condition, const std::vector<Expr> &args);
372
373 Expr memoize_tag_helper(Expr result, const std::vector<Expr> &cache_key_values);
374
375/** Reset the counters used for random-number seeds in random_float/int/uint.
376 * (Note that the counters are incremented for each call, even if a seed is passed in.)
377 * This is used for multitarget compilation to ensure that each subtarget gets
378 * the same sequence of random numbers. */
379 void reset_random_counters();
380
381} // namespace Internal
382
383/** Cast an expression to the halide type corresponding to the C++ type T. */
384 template<typename T>
385 inline Expr cast(Expr a) {
386 return cast(type_of<T>(), std::move(a));
387}
388
389/** Cast an expression to a new type. */
390 Expr cast(Type t, Expr a);
391
392/** Return the sum of two expressions, doing any necessary type
393 * coercion using \ref Internal::match_types */
394 Expr operator+(Expr a, Expr b);
395
396/** Add an expression and a constant integer. Coerces the type of the
397 * integer to match the type of the expression. Errors if the integer
398 * cannot be represented in the type of the expression. */
399// @{
400 Expr operator+(Expr a, int b);
401
402/** Add a constant integer and an expression. Coerces the type of the
403 * integer to match the type of the expression. Errors if the integer
404 * cannot be represented in the type of the expression. */
405 Expr operator+(int a, Expr b);
406
407/** Modify the first expression to be the sum of two expressions,
408 * without changing its type. This casts the second argument to match
409 * the type of the first. */
410 Expr &operator+=(Expr &a, Expr b);
411
412/** Return the difference of two expressions, doing any necessary type
413 * coercion using \ref Internal::match_types */
414 Expr operator-(Expr a, Expr b);
415
416/** Subtracts a constant integer from an expression. Coerces the type of the
417 * integer to match the type of the expression. Errors if the integer
418 * cannot be represented in the type of the expression. */
419 Expr operator-(Expr a, int b);
420
421/** Subtracts an expression from a constant integer. Coerces the type
422 * of the integer to match the type of the expression. Errors if the
423 * integer cannot be represented in the type of the expression. */
424 Expr operator-(int a, Expr b);
425
426/** Return the negative of the argument. Does no type casting, so more
427 * formally: return that number which when added to the original,
428 * yields zero of the same type. For unsigned integers the negative is
429 * still an unsigned integer. E.g. in UInt(8), the negative of 56 is
430 * 200, because 56 + 200 == 0 */
431 Expr operator-(Expr a);
432
433/** Modify the first expression to be the difference of two expressions,
434 * without changing its type. This casts the second argument to match
435 * the type of the first. */
436 Expr &operator-=(Expr &a, Expr b);
437
438/** Return the product of two expressions, doing any necessary type
439 * coercion using \ref Internal::match_types */
440 Expr operator*(Expr a, Expr b);
441
442/** Multiply an expression and a constant integer. Coerces the type of the
443 * integer to match the type of the expression. Errors if the integer
444 * cannot be represented in the type of the expression. */
445 Expr operator*(Expr a, int b);
446
447/** Multiply a constant integer and an expression. Coerces the type of
448 * the integer to match the type of the expression. Errors if the
449 * integer cannot be represented in the type of the expression. */
450 Expr operator*(int a, Expr b);
451
452/** Modify the first expression to be the product of two expressions,
453 * without changing its type. This casts the second argument to match
454 * the type of the first. */
455 Expr &operator*=(Expr &a, Expr b);
456
457/** Return the ratio of two expressions, doing any necessary type
458 * coercion using \ref Internal::match_types. Note that integer
459 * division in Halide is not the same as integer division in C-like
460 * languages in two ways.
461 *
462 * First, signed integer division in Halide rounds according to the
463 * sign of the denominator. This means towards minus infinity for
464 * positive denominators, and towards positive infinity for negative
465 * denominators. This is unlike C, which rounds towards zero. This
466 * decision ensures that upsampling expressions like f(x/2, y/2) don't
467 * have funny discontinuities when x and y cross zero.
468 *
469 * Second, division by zero returns zero instead of faulting. For
470 * types where overflow is defined behavior, division of the largest
471 * negative signed integer by -1 returns the larged negative signed
472 * integer for the type (i.e. it wraps). This ensures that a division
473 * operation can never have a side-effect, which is helpful in Halide
474 * because scheduling directives can expand the domain of computation
475 * of a Func, potentially introducing new zero-division.
476 */
477 Expr operator/(Expr a, Expr b);
478
479/** Modify the first expression to be the ratio of two expressions,
480 * without changing its type. This casts the second argument to match
481 * the type of the first. Note that signed integer division in Halide
482 * rounds towards minus infinity, unlike C, which rounds towards
483 * zero. */
484 Expr &operator/=(Expr &a, Expr b);
485
486/** Divides an expression by a constant integer. Coerces the type
487 * of the integer to match the type of the expression. Errors if the
488 * integer cannot be represented in the type of the expression. */
489 Expr operator/(Expr a, int b);
490
491/** Divides a constant integer by an expression. Coerces the type
492 * of the integer to match the type of the expression. Errors if the
493 * integer cannot be represented in the type of the expression. */
494 Expr operator/(int a, Expr b);
495
496/** Return the first argument reduced modulo the second, doing any
497 * necessary type coercion using \ref Internal::match_types. There are
498 * two key differences between C-like languages and Halide for the
499 * modulo operation, which complement the way division works.
500 *
501 * First, the result is never negative, so x % 2 is always zero or
502 * one, unlike in C-like languages. x % -2 is equivalent, and is also
503 * always zero or one. Second, mod by zero evaluates to zero (unlike
504 * in C, where it faults). This makes modulo, like division, a
505 * side-effect-free operation. */
506 Expr operator%(Expr a, Expr b);
507
508/** Mods an expression by a constant integer. Coerces the type
509 * of the integer to match the type of the expression. Errors if the
510 * integer cannot be represented in the type of the expression. */
511 Expr operator%(Expr a, int b);
512
513/** Mods a constant integer by an expression. Coerces the type
514 * of the integer to match the type of the expression. Errors if the
515 * integer cannot be represented in the type of the expression. */
516 Expr operator%(int a, Expr b);
517
518/** Return a boolean expression that tests whether the first argument
519 * is greater than the second, after doing any necessary type coercion
520 * using \ref Internal::match_types */
521 Expr operator>(Expr a, Expr b);
522
523/** Return a boolean expression that tests whether an expression is
524 * greater than a constant integer. Coerces the integer to the type of
525 * the expression. Errors if the integer is not representable in that
526 * type. */
527 Expr operator>(Expr a, int b);
528
529/** Return a boolean expression that tests whether a constant integer is
530 * greater than an expression. Coerces the integer to the type of
531 * the expression. Errors if the integer is not representable in that
532 * type. */
533 Expr operator>(int a, Expr b);
534
535/** Return a boolean expression that tests whether the first argument
536 * is less than the second, after doing any necessary type coercion
537 * using \ref Internal::match_types */
538 Expr operator<(Expr a, Expr b);
539
540/** Return a boolean expression that tests whether an expression is
541 * less than a constant integer. Coerces the integer to the type of
542 * the expression. Errors if the integer is not representable in that
543 * type. */
544 Expr operator<(Expr a, int b);
545
546/** Return a boolean expression that tests whether a constant integer is
547 * less than an expression. Coerces the integer to the type of
548 * the expression. Errors if the integer is not representable in that
549 * type. */
550 Expr operator<(int a, Expr b);
551
552/** Return a boolean expression that tests whether the first argument
553 * is less than or equal to the second, after doing any necessary type
554 * coercion using \ref Internal::match_types */
555 Expr operator<=(Expr a, Expr b);
556
557/** Return a boolean expression that tests whether an expression is
558 * less than or equal to a constant integer. Coerces the integer to
559 * the type of the expression. Errors if the integer is not
560 * representable in that type. */
561 Expr operator<=(Expr a, int b);
562
563/** Return a boolean expression that tests whether a constant integer
564 * is less 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 Expr operator<=(int a, Expr b);
568
569/** Return a boolean expression that tests whether the first argument
570 * is greater than or equal to the second, after doing any necessary
571 * type coercion using \ref Internal::match_types */
572 Expr operator>=(Expr a, Expr b);
573
574/** Return a boolean expression that tests whether an expression is
575 * greater than or equal to a constant integer. Coerces the integer to
576 * the type of the expression. Errors if the integer is not
577 * representable in that type. */
578 Expr operator>=(const Expr &a, int b);
579
580/** Return a boolean expression that tests whether a constant integer
581 * is greater than or equal to an expression. Coerces the integer to the
582 * type of the expression. Errors if the integer is not representable
583 * in that type. */
584 Expr operator>=(int a, const Expr &b);
585
586/** Return a boolean expression that tests whether the first argument
587 * is equal to the second, after doing any necessary type coercion
588 * using \ref Internal::match_types */
589 Expr operator==(Expr a, Expr b);
590
591/** Return a boolean expression that tests whether an expression is
592 * equal to a constant integer. Coerces the integer to the type of the
593 * expression. Errors if the integer is not representable in that
594 * type. */
595 Expr operator==(Expr a, int b);
596
597/** Return a boolean expression that tests whether a constant integer
598 * is equal to an expression. Coerces the integer to the type of the
599 * expression. Errors if the integer is not representable in that
600 * type. */
601 Expr operator==(int a, Expr b);
602
603/** Return a boolean expression that tests whether the first argument
604 * is not equal to the second, after doing any necessary type coercion
605 * using \ref Internal::match_types */
606 Expr operator!=(Expr a, Expr b);
607
608/** Return a boolean expression that tests whether an expression is
609 * not equal to a constant integer. Coerces the integer to the type of
610 * the expression. Errors if the integer is not representable in that
611 * type. */
612 Expr operator!=(Expr a, int b);
613
614/** Return a boolean expression that tests whether a constant integer
615 * is not equal to an expression. Coerces the integer to the type of
616 * the expression. Errors if the integer is not representable in that
617 * type. */
618 Expr operator!=(int a, Expr b);
619
620/** Returns the logical and of the two arguments */
621 Expr operator&&(Expr a, Expr b);
622
623/** Logical and of an Expr and a bool. Either returns the Expr or an
624 * Expr representing false, depending on the bool. */
625// @{
626 Expr operator&&(Expr a, bool b);
627 Expr operator&&(bool a, Expr b);
628// @}
629
630/** Returns the logical or of the two arguments */
631 Expr operator||(Expr a, Expr b);
632
633/** Logical or of an Expr and a bool. Either returns the Expr or an
634 * Expr representing true, depending on the bool. */
635// @{
636 Expr operator||(Expr a, bool b);
637 Expr operator||(bool a, Expr b);
638// @}
639
640/** Returns the logical not the argument */
641 Expr operator!(Expr a);
642
643/** Returns an expression representing the greater of the two
644 * arguments, after doing any necessary type coercion using
645 * \ref Internal::match_types. Vectorizes cleanly on most platforms
646 * (with the exception of integer types on x86 without SSE4). */
647 Expr max(Expr a, Expr b);
648
649/** Returns an expression representing the greater of an expression
650 * and a constant integer. The integer is coerced to the type of the
651 * expression. Errors if the integer is not representable as that
652 * type. Vectorizes cleanly on most platforms (with the exception of
653 * integer types on x86 without SSE4). */
654 Expr max(Expr a, int b);
655
656/** Returns an expression representing the greater of a constant
657 * integer and an expression. The integer is coerced to the type of
658 * the expression. Errors if the integer is not representable as that
659 * type. Vectorizes cleanly on most platforms (with the exception of
660 * integer types on x86 without SSE4). */
661 Expr max(int a, Expr b);
662
663 inline Expr max(float a, Expr b) {
664 return max(Expr(a), std::move(b));
665}
666 inline Expr max(Expr a, float b) {
667 return max(std::move(a), Expr(b));
668}
669
670/** Returns an expression representing the greater of an expressions
671 * vector, after doing any necessary type coersion using
672 * \ref Internal::match_types. Vectorizes cleanly on most platforms
673 * (with the exception of integer types on x86 without SSE4).
674 * The expressions are folded from right ie. max(.., max(.., ..)).
675 * The arguments can be any mix of types but must all be convertible to Expr. */
676 template<typename A, typename B, typename C, typename... Rest,
677 std::enable_if_t<Internal::all_are_convertible<Expr, Rest...>::value> * = nullptr>
678 inline Expr max(A &&a, B &&b, C &&c, Rest &&...rest) {
679 return max(std::forward<A>(a), max(std::forward<B>(b), std::forward<C>(c), std::forward<Rest>(rest)...));
680}
681
682 Expr min(Expr a, Expr b);
683
684/** Returns an expression representing the lesser of an expression
685 * and a constant integer. The integer is coerced to the type of the
686 * expression. Errors if the integer is not representable as that
687 * type. Vectorizes cleanly on most platforms (with the exception of
688 * integer types on x86 without SSE4). */
689 Expr min(Expr a, int b);
690
691/** Returns an expression representing the lesser of a constant
692 * integer and an expression. The integer is coerced to the type of
693 * the expression. Errors if the integer is not representable as that
694 * type. Vectorizes cleanly on most platforms (with the exception of
695 * integer types on x86 without SSE4). */
696 Expr min(int a, Expr b);
697
698 inline Expr min(float a, Expr b) {
699 return min(Expr(a), std::move(b));
700}
701 inline Expr min(Expr a, float b) {
702 return min(std::move(a), Expr(b));
703}
704
705/** Returns an expression representing the lesser of an expressions
706 * vector, after doing any necessary type coersion using
707 * \ref Internal::match_types. Vectorizes cleanly on most platforms
708 * (with the exception of integer types on x86 without SSE4).
709 * The expressions are folded from right ie. min(.., min(.., ..)).
710 * The arguments can be any mix of types but must all be convertible to Expr. */
711 template<typename A, typename B, typename C, typename... Rest,
712 std::enable_if_t<Internal::all_are_convertible<Expr, Rest...>::value> * = nullptr>
713 inline Expr min(A &&a, B &&b, C &&c, Rest &&...rest) {
714 return min(std::forward<A>(a), min(std::forward<B>(b), std::forward<C>(c), std::forward<Rest>(rest)...));
715}
716
717/** Operators on floats treats those floats as Exprs. Making these
718 * explicit prevents implicit float->int casts that might otherwise
719 * occur. */
720// @{
721 inline Expr operator+(Expr a, float b) {
722 return std::move(a) + Expr(b);
723}
724 inline Expr operator+(float a, Expr b) {
725 return Expr(a) + std::move(b);
726}
727 inline Expr operator-(Expr a, float b) {
728 return std::move(a) - Expr(b);
729}
730 inline Expr operator-(float a, Expr b) {
731 return Expr(a) - std::move(b);
732}
733 inline Expr operator*(Expr a, float b) {
734 return std::move(a) * Expr(b);
735}
736 inline Expr operator*(float a, Expr b) {
737 return Expr(a) * std::move(b);
738}
739 inline Expr operator/(Expr a, float b) {
740 return std::move(a) / Expr(b);
741}
742 inline Expr operator/(float a, Expr b) {
743 return Expr(a) / std::move(b);
744}
745 inline Expr operator%(Expr a, float b) {
746 return std::move(a) % Expr(b);
747}
748 inline Expr operator%(float a, Expr b) {
749 return Expr(a) % std::move(b);
750}
751 inline Expr operator>(Expr a, float b) {
752 return std::move(a) > Expr(b);
753}
754 inline Expr operator>(float a, Expr b) {
755 return Expr(a) > std::move(b);
756}
757 inline Expr operator<(Expr a, float b) {
758 return std::move(a) < Expr(b);
759}
760 inline Expr operator<(float a, Expr b) {
761 return Expr(a) < std::move(b);
762}
763 inline Expr operator>=(Expr a, float b) {
764 return std::move(a) >= Expr(b);
765}
766 inline Expr operator>=(float a, Expr b) {
767 return Expr(a) >= std::move(b);
768}
769 inline Expr operator<=(Expr a, float b) {
770 return std::move(a) <= Expr(b);
771}
772 inline Expr operator<=(float a, Expr b) {
773 return Expr(a) <= std::move(b);
774}
775 inline Expr operator==(Expr a, float b) {
776 return std::move(a) == Expr(b);
777}
778 inline Expr operator==(float a, Expr b) {
779 return Expr(a) == std::move(b);
780}
781 inline Expr operator!=(Expr a, float b) {
782 return std::move(a) != Expr(b);
783}
784 inline Expr operator!=(float a, Expr b) {
785 return Expr(a) != std::move(b);
786}
787// @}
788
789/** Clamps an expression to lie within the given bounds. The bounds
790 * are type-cast to match the expression. Vectorizes as well as min/max. */
791 Expr clamp(Expr a, const Expr &min_val, const Expr &max_val);
792
793/** Returns the absolute value of a signed integer or floating-point
794 * expression. Vectorizes cleanly. Unlike in C, abs of a signed
795 * integer returns an unsigned integer of the same bit width. This
796 * means that abs of the most negative integer doesn't overflow. */
797 Expr abs(Expr a);
798
799/** Return the absolute difference between two values. Vectorizes
800 * cleanly. Returns an unsigned value of the same bit width. There are
801 * various ways to write this yourself, but they contain numerous
802 * gotchas and don't always compile to good code, so use this
803 * instead. */
804 Expr absd(Expr a, Expr b);
805
806/** Returns an expression similar to the ternary operator in C, except
807 * that it always evaluates all arguments. If the first argument is
808 * true, then return the second, else return the third. Typically
809 * vectorizes cleanly, but benefits from SSE41 or newer on x86. */
810 Expr select(Expr condition, Expr true_value, Expr false_value);
811
812/** A multi-way variant of select similar to a switch statement in C,
813 * which can accept multiple conditions and values in pairs. Evaluates
814 * to the first value for which the condition is true. Returns the
815 * final value if all conditions are false. */
816 template<typename... Args,
817 std::enable_if_t<Internal::all_are_convertible<Expr, Args...>::value> * = nullptr>
818 inline Expr select(Expr c0, Expr v0, Expr c1, Expr v1, Args &&...args) {
819 return select(std::move(c0), std::move(v0), select(std::move(c1), std::move(v1), std::forward<Args>(args)...));
820}
821
822/** Equivalent of ternary select(), but taking/returning tuples. If the condition is
823 * a Tuple, it must match the size of the true and false Tuples. */
824// @{
825 Tuple select(const Tuple &condition, const Tuple &true_value, const Tuple &false_value);
826 Tuple select(const Expr &condition, const Tuple &true_value, const Tuple &false_value);
827// @}
828
829/** Equivalent of multiway select(), but taking/returning tuples. If the condition is
830 * a Tuple, it must match the size of the true and false Tuples. */
831// @{
832 template<typename... Args>
833 inline Tuple select(const Tuple &c0, const Tuple &v0, const Tuple &c1, const Tuple &v1, Args &&...args) {
834 return select(c0, v0, select(c1, v1, std::forward<Args>(args)...));
835}
836 template<typename... Args>
837 inline Tuple select(const Expr &c0, const Tuple &v0, const Expr &c1, const Tuple &v1, Args &&...args) {
838 return select(c0, v0, select(c1, v1, std::forward<Args>(args)...));
839}
840// @}
841
842/** select applied to FuncRefs (e.g. select(x < 100, f(x), g(x))) is assumed to
843 * return an Expr. A runtime error is produced if this is applied to
844 * tuple-valued Funcs. In that case you should explicitly cast the second and
845 * third args to Tuple to remove the ambiguity. */
846// @{
847 Expr select(const Expr &condition, const FuncRef &true_value, const FuncRef &false_value);
848 template<typename... Args>
849 inline Expr select(const Expr &c0, const FuncRef &v0, const Expr &c1, const FuncRef &v1, Args &&...args) {
850 return select(c0, v0, select(c1, v1, std::forward<Args>(args)...));
851}
852// @}
853
854/** Oftentimes we want to pack a list of expressions with the same type
855 * into a channel dimension, e.g.,
856 * img(x, y, c) = select(c == 0, 100, // Red
857 * c == 1, 50, // Green
858 * 25); // Blue
859 * This is tedious when the list is long. The following function
860 * provide convinent syntax that allow one to write:
861 * img(x, y, c) = mux(c, {100, 50, 25});
862 *
863 * As with the select equivalent, if the first argument (the index) is
864 * out of range, the expression evaluates to the last value.
865 */
866// @{
867 Expr mux(const Expr &id, const std::initializer_list<Expr> &values);
868 Expr mux(const Expr &id, const std::vector<Expr> &values);
869 Expr mux(const Expr &id, const Tuple &values);
870 Expr mux(const Expr &id, const std::initializer_list<FuncRef> &values);
871 Tuple mux(const Expr &id, const std::initializer_list<Tuple> &values);
872 Tuple mux(const Expr &id, const std::vector<Tuple> &values);
873// @}
874
875/** Return the sine of a floating-point expression. If the argument is
876 * not floating-point, it is cast to Float(32). Does not vectorize
877 * well. */
878 Expr sin(Expr x);
879
880/** Return the arcsine of a floating-point expression. If the argument
881 * is not floating-point, it is cast to Float(32). Does not vectorize
882 * well. */
883 Expr asin(Expr x);
884
885/** Return the cosine of a floating-point expression. If the argument
886 * is not floating-point, it is cast to Float(32). Does not vectorize
887 * well. */
888 Expr cos(Expr x);
889
890/** Return the arccosine of a floating-point expression. If the
891 * argument is not floating-point, it is cast to Float(32). Does not
892 * vectorize well. */
893 Expr acos(Expr x);
894
895/** Return the tangent of a floating-point expression. If the argument
896 * is not floating-point, it is cast to Float(32). Does not vectorize
897 * well. */
898 Expr tan(Expr x);
899
900/** Return the arctangent of a floating-point expression. If the
901 * argument is not floating-point, it is cast to Float(32). Does not
902 * vectorize well. */
903 Expr atan(Expr x);
904
905/** Return the angle of a floating-point gradient. If the argument is
906 * not floating-point, it is cast to Float(32). Does not vectorize
907 * well. */
908 Expr atan2(Expr y, Expr x);
909
910/** Return the hyperbolic sine of a floating-point expression. If the
911 * argument is not floating-point, it is cast to Float(32). Does not
912 * vectorize well. */
913 Expr sinh(Expr x);
914
915/** Return the hyperbolic arcsinhe of a floating-point expression. If
916 * the argument is not floating-point, it is cast to Float(32). Does
917 * not vectorize well. */
918 Expr asinh(Expr x);
919
920/** Return the hyperbolic cosine of a floating-point expression. If
921 * the argument is not floating-point, it is cast to Float(32). Does
922 * not vectorize well. */
923 Expr cosh(Expr x);
924
925/** Return the hyperbolic arccosine of a floating-point expression.
926 * If the argument is not floating-point, it is cast to
927 * Float(32). Does not vectorize well. */
928 Expr acosh(Expr x);
929
930/** Return the hyperbolic tangent of a floating-point expression. If
931 * the argument is not floating-point, it is cast to Float(32). Does
932 * not vectorize well. */
933 Expr tanh(Expr x);
934
935/** Return the hyperbolic arctangent of a floating-point expression.
936 * If the argument is not floating-point, it is cast to
937 * Float(32). Does not vectorize well. */
938 Expr atanh(Expr x);
939
940/** Return the square root of a floating-point expression. If the
941 * argument is not floating-point, it is cast to Float(32). Typically
942 * vectorizes cleanly. */
943 Expr sqrt(Expr x);
944
945/** Return the square root of the sum of the squares of two
946 * floating-point expressions. If the argument is not floating-point,
947 * it is cast to Float(32). Vectorizes cleanly. */
948 Expr hypot(const Expr &x, const Expr &y);
949
950/** Return the exponential of a floating-point expression. If the
951 * argument is not floating-point, it is cast to Float(32). For
952 * Float(64) arguments, this calls the system exp function, and does
953 * not vectorize well. For Float(32) arguments, this function is
954 * vectorizable, does the right thing for extremely small or extremely
955 * large inputs, and is accurate up to the last bit of the
956 * mantissa. Vectorizes cleanly. */
957 Expr exp(Expr x);
958
959/** Return the logarithm of a floating-point expression. If the
960 * argument is not floating-point, it is cast to Float(32). For
961 * Float(64) arguments, this calls the system log function, and does
962 * not vectorize well. For Float(32) arguments, this function is
963 * vectorizable, does the right thing for inputs <= 0 (returns -inf or
964 * nan), and is accurate up to the last bit of the
965 * mantissa. Vectorizes cleanly. */
966 Expr log(Expr x);
967
968/** Return one floating point expression raised to the power of
969 * another. The type of the result is given by the type of the first
970 * argument. If the first argument is not a floating-point type, it is
971 * cast to Float(32). For Float(32), cleanly vectorizable, and
972 * accurate up to the last few bits of the mantissa. Gets worse when
973 * approaching overflow. Vectorizes cleanly. */
974 Expr pow(Expr x, Expr y);
975
976/** Evaluate the error function erf. Only available for
977 * Float(32). Accurate up to the last three bits of the
978 * mantissa. Vectorizes cleanly. */
979 Expr erf(const Expr &x);
980
981/** Fast vectorizable approximation to some trigonometric functions for
982 * Float(32). Absolute approximation error is less than 1e-5. Slow on x86 if
983 * you don't have at least sse 4.1. */
984// @{
985 Expr fast_sin(const Expr &x);
986 Expr fast_cos(const Expr &x);
987// @}
988
989/** Fast approximate cleanly vectorizable log for Float(32). Returns
990 * nonsense for x <= 0.0f. Accurate up to the last 5 bits of the
991 * mantissa. Vectorizes cleanly. Slow on x86 if you don't
992 * have at least sse 4.1. */
993 Expr fast_log(const Expr &x);
994
995/** Fast approximate cleanly vectorizable exp for Float(32). Returns
996 * nonsense for inputs that would overflow or underflow. Typically
997 * accurate up to the last 5 bits of the mantissa. Gets worse when
998 * approaching overflow. Vectorizes cleanly. Slow on x86 if you don't
999 * have at least sse 4.1. */
1000 Expr fast_exp(const Expr &x);
1001
1002/** Fast approximate cleanly vectorizable pow for Float(32). Returns
1003 * nonsense for x < 0.0f. Accurate up to the last 5 bits of the
1004 * mantissa for typical exponents. Gets worse when approaching
1005 * overflow. Vectorizes cleanly. Slow on x86 if you don't
1006 * have at least sse 4.1. */
1007 Expr fast_pow(Expr x, Expr y);
1008
1009/** Fast approximate inverse for Float(32). Corresponds to the rcpps
1010 * instruction on x86, and the vrecpe instruction on ARM. Vectorizes
1011 * cleanly. Note that this can produce slightly different results
1012 * across different implementations of the same architecture (e.g. AMD vs Intel),
1013 * even when strict_float is enabled. */
1014 Expr fast_inverse(Expr x);
1015
1016/** Fast approximate inverse square root for Float(32). Corresponds to
1017 * the rsqrtps instruction on x86, and the vrsqrte instruction on
1018 * ARM. Vectorizes cleanly. Note that this can produce slightly different results
1019 * across different implementations of the same architecture (e.g. AMD vs Intel),
1020 * even when strict_float is enabled. */
1021 Expr fast_inverse_sqrt(Expr x);
1022
1023/** Return the greatest whole number less than or equal to a
1024 * floating-point expression. If the argument is not floating-point,
1025 * it is cast to Float(32). The return value is still in floating
1026 * point, despite being a whole number. Vectorizes cleanly. */
1027 Expr floor(Expr x);
1028
1029/** Return the least whole number greater than or equal to a
1030 * floating-point expression. If the argument is not floating-point,
1031 * it is cast to Float(32). The return value is still in floating
1032 * point, despite being a whole number. Vectorizes cleanly. */
1033 Expr ceil(Expr x);
1034
1035/** Return the whole number closest to a floating-point expression. If the
1036 * argument is not floating-point, it is cast to Float(32). The return value is
1037 * still in floating point, despite being a whole number. On ties, we round
1038 * towards the nearest even integer. Note that this is not the same as
1039 * std::round in C, which rounds away from zero. On platforms without a native
1040 * instruction for this, it is emulated, and may be more expensive than
1041 * cast<int>(x + 0.5f) or similar. */
1042 Expr round(Expr x);
1043
1044/** Return the integer part of a floating-point expression. If the argument is
1045 * not floating-point, it is cast to Float(32). The return value is still in
1046 * floating point, despite being a whole number. Vectorizes cleanly. */
1047 Expr trunc(Expr x);
1048
1049/** Returns true if the argument is a Not a Number (NaN). Requires a
1050 * floating point argument. Vectorizes cleanly.
1051 * Note that the Expr passed in will be evaluated in strict_float mode,
1052 * regardless of whether strict_float mode is enabled in the current Target. */
1053 Expr is_nan(Expr x);
1054
1055/** Returns true if the argument is Inf or -Inf. Requires a
1056 * floating point argument. Vectorizes cleanly.
1057 * Note that the Expr passed in will be evaluated in strict_float mode,
1058 * regardless of whether strict_float mode is enabled in the current Target. */
1059 Expr is_inf(Expr x);
1060
1061/** Returns true if the argument is a finite value (ie, neither NaN nor Inf).
1062 * Requires a floating point argument. Vectorizes cleanly.
1063 * Note that the Expr passed in will be evaluated in strict_float mode,
1064 * regardless of whether strict_float mode is enabled in the current Target. */
1065 Expr is_finite(Expr x);
1066
1067/** Return the fractional part of a floating-point expression. If the argument
1068 * is not floating-point, it is cast to Float(32). The return value has the
1069 * same sign as the original expression. Vectorizes cleanly. */
1070 Expr fract(const Expr &x);
1071
1072/** Reinterpret the bits of one value as another type. */
1073 Expr reinterpret(Type t, Expr e);
1074
1075 template<typename T>
1076 Expr reinterpret(Expr e) {
1077 return reinterpret(type_of<T>(), std::move(e));
1078}
1079
1080/** Return the bitwise and of two expressions (which need not have the
1081 * same type). The result type is the wider of the two expressions.
1082 * Only integral types are allowed and both expressions must be signed
1083 * or both must be unsigned. */
1084 Expr operator&(Expr x, Expr y);
1085
1086/** Return the bitwise and of an expression and an integer. The type
1087 * of the result is the type of the expression argument. */
1088// @{
1089 Expr operator&(Expr x, int y);
1090 Expr operator&(int x, Expr y);
1091// @}
1092
1093/** Return the bitwise or of two expressions (which need not have the
1094 * same type). The result type is the wider of the two expressions.
1095 * Only integral types are allowed and both expressions must be signed
1096 * or both must be unsigned. */
1097 Expr operator|(Expr x, Expr y);
1098
1099/** Return the bitwise or of an expression and an integer. The type of
1100 * the result is the type of the expression argument. */
1101// @{
1102 Expr operator|(Expr x, int y);
1103 Expr operator|(int x, Expr y);
1104// @}
1105
1106/** Return the bitwise xor of two expressions (which need not have the
1107 * same type). The result type is the wider of the two expressions.
1108 * Only integral types are allowed and both expressions must be signed
1109 * or both must be unsigned. */
1110 Expr operator^(Expr x, Expr y);
1111
1112/** Return the bitwise xor of an expression and an integer. The type
1113 * of the result is the type of the expression argument. */
1114// @{
1115 Expr operator^(Expr x, int y);
1116 Expr operator^(int x, Expr y);
1117// @}
1118
1119/** Return the bitwise not of an expression. */
1120 Expr operator~(Expr x);
1121
1122/** Shift the bits of an integer value left. This is actually less
1123 * efficient than multiplying by 2^n, because Halide's optimization
1124 * passes understand multiplication, and will compile it to
1125 * shifting. This operator is only for if you really really need bit
1126 * shifting (e.g. because the exponent is a run-time parameter). The
1127 * type of the result is equal to the type of the first argument. Both
1128 * arguments must have integer type. */
1129// @{
1130 Expr operator<<(Expr x, Expr y);
1131 Expr operator<<(Expr x, int y);
1132// @}
1133
1134/** Shift the bits of an integer value right. Does sign extension for
1135 * signed integers. This is less efficient than dividing by a power of
1136 * two. Halide's definition of division (always round to negative
1137 * infinity) means that all divisions by powers of two get compiled to
1138 * bit-shifting, and Halide's optimization routines understand
1139 * division and can work with it. The type of the result is equal to
1140 * the type of the first argument. Both arguments must have integer
1141 * type. */
1142// @{
1143 Expr operator>>(Expr x, Expr y);
1144 Expr operator>>(Expr x, int y);
1145// @}
1146
1147/** Linear interpolate between the two values according to a weight.
1148 * \param zero_val The result when weight is 0
1149 * \param one_val The result when weight is 1
1150 * \param weight The interpolation amount
1151 *
1152 * Both zero_val and one_val must have the same type. All types are
1153 * supported, including bool.
1154 *
1155 * The weight is treated as its own type and must be float or an
1156 * unsigned integer type. It is scaled to the bit-size of the type of
1157 * x and y if they are integer, or converted to float if they are
1158 * float. Integer weights are converted to float via division by the
1159 * full-range value of the weight's type. Floating-point weights used
1160 * to interpolate between integer values must be between 0.0f and
1161 * 1.0f, and an error may be signaled if it is not provably so. (clamp
1162 * operators can be added to provide proof. Currently an error is only
1163 * signalled for constant weights.)
1164 *
1165 * For integer linear interpolation, out of range values cannot be
1166 * represented. In particular, weights that are conceptually less than
1167 * 0 or greater than 1.0 are not representable. As such the result is
1168 * always between x and y (inclusive of course). For lerp with
1169 * floating-point values and floating-point weight, the full range of
1170 * a float is valid, however underflow and overflow can still occur.
1171 *
1172 * Ordering is not required between zero_val and one_val:
1173 * lerp(42, 69, .5f) == lerp(69, 42, .5f) == 56
1174 *
1175 * Results for integer types are for exactly rounded arithmetic. As
1176 * such, there are cases where 16-bit and float differ because 32-bit
1177 * floating-point (float) does not have enough precision to produce
1178 * the exact result. (Likely true for 32-bit integer
1179 * vs. double-precision floating-point as well.)
1180 *
1181 * At present, double precision and 64-bit integers are not supported.
1182 *
1183 * Generally, lerp will vectorize as if it were an operation on a type
1184 * twice the bit size of the inferred type for x and y.
1185 *
1186 * Some examples:
1187 * \code
1188 *
1189 * // Since Halide does not have direct type delcarations, casts
1190 * // below are used to indicate the types of the parameters.
1191 * // Such casts not required or expected in actual code where types
1192 * // are inferred.
1193 *
1194 * lerp(cast<float>(x), cast<float>(y), cast<float>(w)) ->
1195 * x * (1.0f - w) + y * w
1196 *
1197 * lerp(cast<uint8_t>(x), cast<uint8_t>(y), cast<uint8_t>(w)) ->
1198 * cast<uint8_t>(cast<uint8_t>(x) * (1.0f - cast<uint8_t>(w) / 255.0f) +
1199 * cast<uint8_t>(y) * cast<uint8_t>(w) / 255.0f + .5f)
1200 *
1201 * // Note addition in Halide promoted uint8_t + int8_t to int16_t already,
1202 * // the outer cast is added for clarity.
1203 * lerp(cast<uint8_t>(x), cast<int8_t>(y), cast<uint8_t>(w)) ->
1204 * cast<int16_t>(cast<uint8_t>(x) * (1.0f - cast<uint8_t>(w) / 255.0f) +
1205 * cast<int8_t>(y) * cast<uint8_t>(w) / 255.0f + .5f)
1206 *
1207 * lerp(cast<int8_t>(x), cast<int8_t>(y), cast<float>(w)) ->
1208 * cast<int8_t>(cast<int8_t>(x) * (1.0f - cast<float>(w)) +
1209 * cast<int8_t>(y) * cast<uint8_t>(w))
1210 *
1211 * \endcode
1212 * */
1213 Expr lerp(Expr zero_val, Expr one_val, Expr weight);
1214
1215/** Count the number of set bits in an expression. */
1216 Expr popcount(Expr x);
1217
1218/** Count the number of leading zero bits in an expression. If the expression is
1219 * zero, the result is the number of bits in the type. */
1220 Expr count_leading_zeros(Expr x);
1221
1222/** Count the number of trailing zero bits in an expression. If the expression is
1223 * zero, the result is the number of bits in the type. */
1224 Expr count_trailing_zeros(Expr x);
1225
1226/** Divide two integers, rounding towards zero. This is the typical
1227 * behavior of most hardware architectures, which differs from
1228 * Halide's division operator, which is Euclidean (rounds towards
1229 * -infinity). Will throw a runtime error if y is zero, or if y is -1
1230 * and x is the minimum signed integer. */
1231 Expr div_round_to_zero(Expr x, Expr y);
1232
1233/** Compute the remainder of dividing two integers, when division is
1234 * rounding toward zero. This is the typical behavior of most hardware
1235 * architectures, which differs from Halide's mod operator, which is
1236 * Euclidean (produces the remainder when division rounds towards
1237 * -infinity). Will throw a runtime error if y is zero. */
1238 Expr mod_round_to_zero(Expr x, Expr y);
1239
1240/** Return a random variable representing a uniformly distributed
1241 * float in the half-open interval [0.0f, 1.0f). For random numbers of
1242 * other types, use lerp with a random float as the last parameter.
1243 *
1244 * Optionally takes a seed.
1245 *
1246 * Note that:
1247 \code
1248 Expr x = random_float();
1249 Expr y = x + x;
1250 \endcode
1251 *
1252 * is very different to
1253 *
1254 \code
1255 Expr y = random_float() + random_float();
1256 \endcode
1257 *
1258 * The first doubles a random variable, and the second adds two
1259 * independent random variables.
1260 *
1261 * A given random variable takes on a unique value that depends
1262 * deterministically on the pure variables of the function they belong
1263 * to, the identity of the function itself, and which definition of
1264 * the function it is used in. They are, however, shared across tuple
1265 * elements.
1266 *
1267 * This function vectorizes cleanly.
1268 */
1269 Expr random_float(Expr seed = Expr());
1270
1271/** Return a random variable representing a uniformly distributed
1272 * unsigned 32-bit integer. See \ref random_float. Vectorizes cleanly. */
1273 Expr random_uint(Expr seed = Expr());
1274
1275/** Return a random variable representing a uniformly distributed
1276 * 32-bit integer. See \ref random_float. Vectorizes cleanly. */
1277 Expr random_int(Expr seed = Expr());
1278
1279/** Create an Expr that prints out its value whenever it is
1280 * evaluated. It also prints out everything else in the arguments
1281 * list, separated by spaces. This can include string literals. */
1282//@{
1283 Expr print(const std::vector<Expr> &values);
1284
1285 template<typename... Args>
1286 inline HALIDE_NO_USER_CODE_INLINE Expr print(Expr a, Args &&...args) {
1287 std::vector<Expr> collected_args = {std::move(a)};
1288 Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
1289 return print(collected_args);
1290}
1291//@}
1292
1293/** Create an Expr that prints whenever it is evaluated, provided that
1294 * the condition is true. */
1295// @{
1296 Expr print_when(Expr condition, const std::vector<Expr> &values);
1297
1298 template<typename... Args>
1299 inline HALIDE_NO_USER_CODE_INLINE Expr print_when(Expr condition, Expr a, Args &&...args) {
1300 std::vector<Expr> collected_args = {std::move(a)};
1301 Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
1302 return print_when(std::move(condition), collected_args);
1303}
1304
1305// @}
1306
1307/** Create an Expr that that guarantees a precondition.
1308 * If 'condition' is true, the return value is equal to the first Expr.
1309 * If 'condition' is false, halide_error() is called, and the return value
1310 * is arbitrary. Any additional arguments after the first Expr are stringified
1311 * and passed as a user-facing message to halide_error(), similar to print().
1312 *
1313 * Note that this essentially *always* inserts a runtime check into the
1314 * generated code (except when the condition can be proven at compile time);
1315 * as such, it should be avoided inside inner loops, except for debugging
1316 * or testing purposes. Note also that it does not vectorize cleanly (vector
1317 * values will be scalarized for the check).
1318 *
1319 * However, using this to make assertions about (say) input values
1320 * can be useful, both in terms of correctness and (potentially) in terms
1321 * of code generation, e.g.
1322 \code
1323 Param<int> p;
1324 Expr y = require(p > 0, p);
1325 \endcode
1326 * will allow the optimizer to assume positive, nonzero values for y.
1327 */
1328// @{
1329 Expr require(Expr condition, const std::vector<Expr> &values);
1330
1331 template<typename... Args>
1332 inline HALIDE_NO_USER_CODE_INLINE Expr require(Expr condition, Expr value, Args &&...args) {
1333 std::vector<Expr> collected_args = {std::move(value)};
1334 Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
1335 return require(std::move(condition), collected_args);
1336}
1337// @}
1338
1339/** Return an undef value of the given type. Halide skips stores that
1340 * depend on undef values, so you can use this to mean "do not modify
1341 * this memory location". This is an escape hatch that can be used for
1342 * several things:
1343 *
1344 * You can define a reduction with no pure step, by setting the pure
1345 * step to undef. Do this only if you're confident that the update
1346 * steps are sufficient to correctly fill in the domain.
1347 *
1348 * For a tuple-valued reduction, you can write an update step that
1349 * only updates some tuple elements.
1350 *
1351 * You can define single-stage pipeline that only has update steps,
1352 * and depends on the values already in the output buffer.
1353 *
1354 * Use this feature with great caution, as you can use it to load from
1355 * uninitialized memory.
1356 */
1357 Expr undef(Type t);
1358
1359 template<typename T>
1360 inline Expr undef() {
1361 return undef(type_of<T>());
1362}
1363
1364 namespace Internal {
1365
1366/** Return an expression that should never be evaluated. Expressions
1367 * that depend on unreachabale values are also unreachable, and
1368 * statements that execute unreachable expressions are also considered
1369 * unreachable. */
1370 Expr unreachable(Type t = Int(32));
1371
1372 template<typename T>
1373 inline Expr unreachable() {
1374 return unreachable(type_of<T>());
1375}
1376
1377} // namespace Internal
1378
1379/** Control the values used in the memoization cache key for memoize.
1380 * Normally parameters and other external dependencies are
1381 * automatically inferred and added to the cache key. The memoize_tag
1382 * operator allows computing one expression and using either the
1383 * computed value, or one or more other expressions in the cache key
1384 * instead of the parameter dependencies of the computation. The
1385 * single argument version is completely safe in that the cache key
1386 * will use the actual computed value -- it is difficult or imposible
1387 * to produce erroneous caching this way. The more-than-one argument
1388 * version allows generating cache keys that do not uniquely identify
1389 * the computation and thus can result in caching errors.
1390 *
1391 * A potential use for the single argument version is to handle a
1392 * floating-point parameter that is quantized to a small
1393 * integer. Mutliple values of the float will produce the same integer
1394 * and moving the caching to using the integer for the key is more
1395 * efficient.
1396 *
1397 * The main use for the more-than-one argument version is to provide
1398 * cache key information for Handles and ImageParams, which otherwise
1399 * are not allowed inside compute_cached operations. E.g. when passing
1400 * a group of parameters to an external array function via a Handle,
1401 * memoize_tag can be used to isolate the actual values used by that
1402 * computation. If an ImageParam is a constant image with a persistent
1403 * digest, memoize_tag can be used to key computations using that image
1404 * on the digest. */
1405// @{
1406 template<typename... Args>
1407 inline HALIDE_NO_USER_CODE_INLINE Expr memoize_tag(Expr result, Args &&...args) {
1408 std::vector<Expr> collected_args{std::forward<Args>(args)...};
1409 return Internal::memoize_tag_helper(std::move(result), collected_args);
1410}
1411// @}
1412
1413/** Expressions tagged with this intrinsic are considered to be part
1414 * of the steady state of some loop with a nasty beginning and end
1415 * (e.g. a boundary condition). When Halide encounters likely
1416 * intrinsics, it splits the containing loop body into three, and
1417 * tries to simplify down all conditions that lead to the likely. For
1418 * example, given the expression: select(x < 1, bar, x > 10, bar,
1419 * likely(foo)), Halide will split the loop over x into portions where
1420 * x < 1, 1 <= x <= 10, and x > 10.
1421 *
1422 * You're unlikely to want to call this directly. You probably want to
1423 * use the boundary condition helpers in the BoundaryConditions
1424 * namespace instead.
1425 */
1426 Expr likely(Expr e);
1427
1428/** Equivalent to likely, but only triggers a loop partitioning if
1429 * found in an innermost loop. */
1430 Expr likely_if_innermost(Expr e);
1431
1432/** Cast an expression to the halide type corresponding to the C++
1433 * type T. As part of the cast, clamp to the minimum and maximum
1434 * values of the result type. */
1435 template<typename T>
1436 Expr saturating_cast(Expr e) {
1437 return saturating_cast(type_of<T>(), std::move(e));
1438}
1439
1440/** Cast an expression to a new type, clamping to the minimum and
1441 * maximum values of the result type. */
1442 Expr saturating_cast(Type t, Expr e);
1443
1444/** Makes a best effort attempt to preserve IEEE floating-point
1445 * semantics in evaluating an expression. May not be implemented for
1446 * all backends. (E.g. it is difficult to do this for C++ code
1447 * generation as it depends on the compiler flags used to compile the
1448 * generated code. */
1449 Expr strict_float(const Expr &e);
1450
1451/** Create an Expr that that promises another Expr is clamped but do
1452 * not generate code to check the assertion or modify the value. No
1453 * attempt is made to prove the bound at compile time. (If it is
1454 * proved false as a result of something else, an error might be
1455 * generated, but it is also possible the compiler will crash.) The
1456 * promised bound is used in bounds inference so it will allow
1457 * satisfying bounds checks as well as possibly aiding optimization.
1458 *
1459 * unsafe_promise_clamped returns its first argument, the Expr 'value'
1460 *
1461 * This is a very easy way to make Halide generate erroneous code if
1462 * the bound promises is not kept. Use sparingly when there is no
1463 * other way to convey the information to the compiler and it is
1464 * required for a valuable optimization.
1465 *
1466 * Unsafe promises can be checked by turning on
1467 * Target::CheckUnsafePromises. This is intended for debugging only.
1468 */
1469 Expr unsafe_promise_clamped(const Expr &value, const Expr &min, const Expr &max);
1470
1471 namespace Internal {
1472/**
1473 * FOR INTERNAL USE ONLY.
1474 *
1475 * An entirely unchecked version of unsafe_promise_clamped, used
1476 * inside the compiler as an annotation of the known bounds of an Expr
1477 * when it has proved something is bounded and wants to record that
1478 * fact for later passes (notably bounds inference) to exploit. This
1479 * gets introduced by GuardWithIf tail strategies, because the bounds
1480 * machinery has a hard time exploiting if statement conditions.
1481 *
1482 * Unlike unsafe_promise_clamped, this expression is
1483 * context-dependent, because 'value' might be statically bounded at
1484 * some point in the IR (e.g. due to a containing if statement), but
1485 * not elsewhere.
1486 *
1487 * This intrinsic always evaluates to its first argument. If this value is
1488 * used by a side-effecting operation and it is outside the range specified
1489 * by its second and third arguments, behavior is undefined. The compiler can
1490 * therefore assume that the value is within the range given and optimize
1491 * accordingly. Note that this permits promise_clamped to evaluate to
1492 * something outside of the range, provided that this value is not used.
1493 *
1494 * Note that this produces an intrinsic that is marked as 'pure' and thus is
1495 * allowed to be hoisted, etc.; thus, extra care must be taken with its use.
1496 **/
1497 Expr promise_clamped(const Expr &value, const Expr &min, const Expr &max);
1498} // namespace Internal
1499
1500/** Scatter and gather are used for update definition which must store
1501 * multiple values to distinct locations at the same time. The
1502 * multiple expressions on the right-hand-side are bundled together
1503 * into a "gather", which must match a "scatter" the the same number
1504 * of arguments on the left-hand-size. For example, to store the
1505 * values 1 and 2 to the locations (x, y, 3) and (x, y, 4),
1506 * respectively:
1507 *
1508\code
1509 f(x, y, scatter(3, 4)) = gather(1, 2);
1510\endcode
1511 *
1512 * The result of gather or scatter can be treated as an
1513 * expression. Any containing operations on it can be assumed to
1514 * distribute over the elements. If two gather expressions are
1515 * combined with an arithmetic operator (e.g. added), they combine
1516 * element-wise. The following example stores the values 2 * x, 2 * y,
1517 * and 2 * c to the locations (x + 1, y, c), (x, y + 3, c), and (x, y,
1518 * c + 2) respectively:
1519 *
1520\code
1521 f(x + scatter(1, 0, 0), y + scatter(0, 3, 0), c + scatter(0, 0, 2)) = 2 * gather(x, y, c);
1522\endcode
1523*
1524* Repeated values in the scatter cause multiple stores to the same
1525* location. The stores happen in order from left to right, so the
1526* rightmost value wins. The following code is equivalent to f(x) = 5
1527*
1528\code
1529 f(scatter(x, x)) = gather(3, 5);
1530\endcode
1531*
1532* Gathers are most useful for algorithms which require in-place
1533* swapping or permutation of multiple elements, or other kinds of
1534* in-place mutations that require loading multiple inputs, doing some
1535* operations to them jointly, then storing them again. The following
1536* update definition swaps the values of f at locations 3 and 5 if an
1537* input parameter p is true:
1538*
1539\code
1540 f(scatter(3, 5)) = f(select(p, gather(5, 3), gather(3, 5)));
1541\endcode
1542*
1543* For more examples of the use of scatter and gather, see
1544* test/correctness/multiple_scatter.cpp
1545*
1546* It is not currently possible to use scatter and gather to write an
1547* update definition in which the *number* of values loaded or stored
1548* varies, as the size of the scatter/gather packet must be fixed a
1549* compile-time. A workaround is to make the unwanted extra operations
1550* a redundant copy of the last operation, which will be
1551* dead-code-eliminated by the compiler. For example, the following
1552* update definition swaps the values at locations 3 and 5 when the
1553* parameter p is true, and rotates the values at locations 1, 2, and 3
1554* when it is false. The load from 3 and store to 5 will be redundantly
1555* repeated:
1556*
1557\code
1558 f(select(p, scatter(3, 5, 5), scatter(1, 2, 3))) = f(select(p, gather(5, 3, 3), gather(2, 3, 1)));
1559\endcode
1560*
1561* Note that in the p == true case, we redundantly load from 3 and write
1562* to 5 twice.
1563*/
1564//@{
1565 Expr scatter(const std::vector<Expr> &args);
1566 Expr gather(const std::vector<Expr> &args);
1567
1568 template<typename... Args>
1569 Expr scatter(const Expr &e, Args &&...args) {
1570 return scatter({e, std::forward<Args>(args)...});
1571}
1572
1573 template<typename... Args>
1574 Expr gather(const Expr &e, Args &&...args) {
1575 return gather({e, std::forward<Args>(args)...});
1576}
1577// @}
1578
1579/** Extract a contiguous subsequence of the bits of 'e', starting at the bit
1580 * index given by 'lsb', where zero is the least-significant bit, returning a
1581 * value of type 't'. Any out-of-range bits requested are filled with zeros.
1582 *
1583 * extract_bits is especially useful when one wants to load a small vector of a
1584 * wide type, and treat it as a larger vector of a smaller type. For example,
1585 * loading a vector of 32 uint8 values from a uint32 Func can be done as
1586 * follows:
1587\code
1588 f8(x) = extract_bits<uint8_t>(f32(x/4), 8*(x%4));
1589 f8.align_bounds(x, 4).vectorize(x, 32);
1590\endcode
1591 * Note that the align_bounds call is critical so that the narrow Exprs are
1592 * aligned to the wider Exprs. This makes the x%4 term collapse to a
1593 * constant. If f8 is an output Func, then constraining the min value of x to be
1594 * a known multiple of four would also be sufficient, e.g. via:
1595\code
1596 f8.output_buffer().dim(0).set_min(0);
1597\endcode
1598 *
1599 * See test/correctness/extract_concat_bits.cpp for a complete example. */
1600// @{
1601 Expr extract_bits(Type t, const Expr &e, const Expr &lsb);
1602
1603 template<typename T>
1604 Expr extract_bits(const Expr &e, const Expr &lsb) {
1605 return extract_bits(type_of<T>(), e, lsb);
1606}
1607// @}
1608
1609/** Given a number of Exprs of the same type, concatenate their bits producing a
1610 * single Expr of the same type code of the input but with more bits. The
1611 * number of arguments must be a power of two.
1612 *
1613 * concat_bits is especially useful when one wants to treat a Func containing
1614 * values of a narrow type as a Func containing fewer values of a wider
1615 * type. For example, the following code reinterprets vectors of 32 uint8 values
1616 * as a vector of 8 uint32s:
1617 *
1618\code
1619 f32(x) = concat_bits({f8(4*x), f8(4*x + 1), f8(4*x + 2), f8(4*x + 3)});
1620 f32.vectorize(x, 8);
1621\endcode
1622 *
1623 * See test/correctness/extract_concat_bits.cpp for a complete example.
1624 */
1625 Expr concat_bits(const std::vector<Expr> &e);
1626
1627/** Below is a collection of intrinsics for fixed-point programming. Most of
1628 * them can be expressed via other means, but this is more natural for some, as
1629 * it avoids ghost widened intermediates that don't (or shouldn't) actually show
1630 * up in codegen, and doesn't rely on pattern-matching inside the compiler to
1631 * succeed to get good instruction selection.
1632 *
1633 * The semantics of each call are defined in terms of a non-existent 'widen' and
1634 * 'narrow' operators, which stand in for casts that double or halve the
1635 * bit-width of a type respectively.
1636 */
1637
1638/** Compute a + widen(b). */
1639 Expr widen_right_add(Expr a, Expr b);
1640
1641/** Compute a * widen(b). */
1642 Expr widen_right_mul(Expr a, Expr b);
1643
1644/** Compute a - widen(b). */
1645 Expr widen_right_sub(Expr a, Expr b);
1646
1647/** Compute widen(a) + widen(b). */
1648 Expr widening_add(Expr a, Expr b);
1649
1650/** Compute widen(a) * widen(b). a and b may have different signedness, in which
1651 * case the result is signed. */
1652 Expr widening_mul(Expr a, Expr b);
1653
1654/** Compute widen(a) - widen(b). The result is always signed. */
1655 Expr widening_sub(Expr a, Expr b);
1656
1657/** Compute widen(a) << b. */
1658//@{
1659 Expr widening_shift_left(Expr a, Expr b);
1660 Expr widening_shift_left(Expr a, int b);
1661//@}
1662
1663/** Compute widen(a) >> b. */
1664//@{
1665 Expr widening_shift_right(Expr a, Expr b);
1666 Expr widening_shift_right(Expr a, int b);
1667//@}
1668
1669/** Compute saturating_narrow(widening_add(a, (1 >> min(b, 0)) / 2) << b).
1670 * When b is positive indicating a left shift, the rounding term is zero. */
1671//@{
1672 Expr rounding_shift_left(Expr a, Expr b);
1673 Expr rounding_shift_left(Expr a, int b);
1674//@}
1675
1676/** Compute saturating_narrow(widening_add(a, (1 << max(b, 0)) / 2) >> b).
1677 * When b is negative indicating a left shift, the rounding term is zero. */
1678//@{
1679 Expr rounding_shift_right(Expr a, Expr b);
1680 Expr rounding_shift_right(Expr a, int b);
1681//@}
1682
1683/** Compute saturating_narrow(widen(a) + widen(b)) */
1684 Expr saturating_add(Expr a, Expr b);
1685
1686/** Compute saturating_narrow(widen(a) - widen(b)) */
1687 Expr saturating_sub(Expr a, Expr b);
1688
1689/** Compute narrow((widen(a) + widen(b)) / 2) */
1690 Expr halving_add(Expr a, Expr b);
1691
1692/** Compute narrow((widen(a) + widen(b) + 1) / 2) */
1693 Expr rounding_halving_add(Expr a, Expr b);
1694
1695/** Compute narrow((widen(a) - widen(b)) / 2) */
1696 Expr halving_sub(Expr a, Expr b);
1697
1698/** Compute saturating_narrow(shift_right(widening_mul(a, b), q)) */
1699//@{
1700 Expr mul_shift_right(Expr a, Expr b, Expr q);
1701 Expr mul_shift_right(Expr a, Expr b, int q);
1702//@}
1703
1704/** Compute saturating_narrow(rounding_shift_right(widening_mul(a, b), q)) */
1705//@{
1706 Expr rounding_mul_shift_right(Expr a, Expr b, Expr q);
1707 Expr rounding_mul_shift_right(Expr a, Expr b, int q);
1708//@}
1709
1710/** Return a boolean Expr for the corresponding field of the Target
1711 * being used during lowering; they can be useful in writing library
1712 * code without having to plumb a Target through call sites, so that you
1713 * can do things like
1714 \code
1715 Expr e = select(target_arch_is(Target::ARM), something, something_else);
1716 \endcode
1717 * Note that this doesn't do any checking at runtime to verify that the Target
1718 * is valid for the current hardware configuration.
1719 */
1720//@{
1721 Expr target_arch_is(Target::Arch arch);
1722 Expr target_os_is(Target::OS os);
1723 Expr target_has_feature(Target::Feature feat);
1724//@}
1725
1726/** Return the bit width of the Target used during lowering; this can be useful
1727 * in writing library code without having to plumb a Target through call sites,
1728 * so that you can do things like
1729 \code
1730 Expr e = select(target_bits() == 32, something, something_else);
1731 \endcode
1732 * Note that this doesn't do any checking at runtime to verify that the Target
1733 * is valid for the current hardware configuration.
1734 */
1735 Expr target_bits();
1736
1737/** Return the natural vector width for the given Type for the Target
1738 * being used during lowering; this can be useful in writing library
1739 * code without having to plumb a Target through call sites, so that you
1740 * can do things like
1741 \code
1742 f.vectorize(x, target_natural_vector_size(Float(32)));
1743 \endcode
1744 * Note that this doesn't do any checking at runtime to verify that the Target
1745 * is valid for the current hardware configuration.
1746 */
1747//@{
1748 Expr target_natural_vector_size(Type t);
1749 template<typename data_t>
1750 Expr target_natural_vector_size() {
1751 return target_natural_vector_size(type_of<data_t>());
1752}
1753//@}
1754
1755} // namespace Halide
1756
1757#endif
ConstantInterval.h
Defines the ConstantInterval class, and operators on it.
Expr.h
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
Scope.h
Defines the Scope class, which is used for keeping track of names in a scope while traversing IR.
Target.h
Defines the structure that describes a Halide target.
Tuple.h
Defines Tuple - the front-end handle on small arrays of expressions.
HALIDE_NO_USER_CODE_INLINE
#define HALIDE_NO_USER_CODE_INLINE
Definition: Util.h:47
Halide::FuncRef
A fragment of front-end syntax of the form f(x, y, z), where x, y, z are Vars or Exprs.
Definition: Func.h:494
Halide::Internal::Scope
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
Definition: Scope.h:94
Halide::Tuple
Create a small array of Exprs for defining and calling functions with multiple outputs.
Definition: Tuple.h:18
Halide::Internal::make_one
Expr make_one(Type t)
Construct the representation of one in the given type.
Halide::Internal::div_imp
T div_imp(T a, T b)
Definition: IROperator.h:278
Halide::Internal::is_const_zero
bool is_const_zero(const Expr &e)
Is the expression a const (as defined by is_const), and also equal to zero (in all lanes,...
Halide::Internal::as_const_int
std::optional< int64_t > as_const_int(const Expr &e)
If an expression is an IntImm or a Broadcast of an IntImm, return a its value.
Halide::Internal::memoize_tag_helper
Expr memoize_tag_helper(Expr result, const std::vector< Expr > &cache_key_values)
Halide::Internal::make_zero
Expr make_zero(Type t)
Construct the representation of zero in the given type.
Halide::Internal::is_negative_const
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,...
Halide::Internal::is_undef
bool is_undef(const Expr &e)
Is the expression an undef.
Halide::Internal::as_const_uint
std::optional< uint64_t > as_const_uint(const Expr &e)
If an expression is a UIntImm or a Broadcast of a UIntImm, return its value.
Halide::Internal::requirement_failed_error
Expr requirement_failed_error(Expr condition, const std::vector< Expr > &args)
Halide::Internal::make_two
Expr make_two(Type t)
Construct the representation of two in the given type.
Halide::Internal::unreachable
Expr unreachable(Type t=Int(32))
Return an expression that should never be evaluated.
Halide::Internal::check_representable
void check_representable(Type t, int64_t val)
Check if a constant value can be correctly represented as the given type.
Halide::Internal::halide_erf
Expr halide_erf(const Expr &a)
Halide::Internal::is_const_one
bool is_const_one(const Expr &e)
Is the expression a const (as defined by is_const), and also equal to one (in all lanes,...
Halide::Internal::match_types
void match_types(Expr &a, Expr &b)
Coerce the two expressions to have the same type, using C-style casting rules.
Halide::Internal::div_imp< double >
double div_imp< double >(double a, double b)
Definition: IROperator.h:319
Halide::Internal::min
ConstantInterval min(const ConstantInterval &a, const ConstantInterval &b)
Halide::Internal::as_const_float
std::optional< double > as_const_float(const Expr &e)
If an expression is a FloatImm or a Broadcast of a FloatImm, return its value.
Halide::Internal::halide_exp
Expr halide_exp(const Expr &a)
Halide::Internal::make_const
Expr make_const(Type t, int64_t val)
Construct an immediate of the given type from any numeric C++ type.
Halide::Internal::is_const_power_of_two_integer
std::optional< int > is_const_power_of_two_integer(const Expr &e)
Is the expression a constant integer power of two.
Halide::Internal::is_positive_const
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...
Halide::Internal::const_true
Expr const_true(int lanes=1)
Construct the constant boolean true.
Halide::Internal::max
ConstantInterval max(const ConstantInterval &a, const ConstantInterval &b)
Halide::Internal::is_signed_integer_overflow
bool is_signed_integer_overflow(const Expr &expr)
Check if an expression is a signed_integer_overflow.
Halide::Internal::mod_imp
T mod_imp(T a, T b)
Implementations of division and mod that are specific to Halide.
Definition: IROperator.h:257
Halide::Internal::reset_random_counters
void reset_random_counters()
Reset the counters used for random-number seeds in random_float/int/uint.
Halide::Internal::halide_log
Expr halide_log(const Expr &a)
Halide's vectorizable transcendentals.
Halide::Internal::is_pure
bool is_pure(const Expr &e)
Does the expression 1) Take on the same value no matter where it appears in a Stmt,...
Halide::Internal::split_into_ands
void split_into_ands(const Expr &cond, std::vector< Expr > &result)
Split a boolean condition into vector of ANDs.
Halide::Internal::promise_clamped
Expr promise_clamped(const Expr &value, const Expr &min, const Expr &max)
FOR INTERNAL USE ONLY.
Halide::Internal::is_no_op
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...
Halide::Internal::unwrap_tags
Expr unwrap_tags(const Expr &e)
If the expression is a tag helper call, remove it and return the tagged expression.
Halide::Internal::div_imp< float >
float div_imp< float >(float a, float b)
Definition: IROperator.h:315
Halide::Internal::all_are_printable_args_v
constexpr bool all_are_printable_args_v
Definition: IROperator.h:353
Halide::Internal::lossless_negate
Expr lossless_negate(const Expr &x)
Attempt to negate x without introducing new IR and without overflow.
Halide::Internal::strided_ramp_base
Expr strided_ramp_base(const Expr &e, int stride=1)
If e is a ramp expression with stride, default 1, return the base, otherwise undefined.
Halide::Internal::remove_promises
Expr remove_promises(const Expr &e)
Return an Expr that is identical to the input Expr, but with all calls to promise_clamped() and unsaf...
Halide::Internal::const_false
Expr const_false(int lanes=1)
Construct the constant boolean false.
Halide::Internal::lossless_cast
Expr lossless_cast(Type t, Expr e, const Scope< ConstantInterval > &scope=Scope< ConstantInterval >::empty_scope(), std::map< Expr, ConstantInterval, ExprCompare > *cache=nullptr)
Attempt to cast an expression to a smaller type while provably not losing information.
Halide::Internal::mod_imp< double >
double mod_imp< double >(double a, double b)
Definition: IROperator.h:309
Halide::Internal::make_bool
Expr make_bool(bool val, int lanes=1)
Construct a boolean constant from a C++ boolean value.
Halide::Internal::collect_print_args
HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector< Expr > &args)
Definition: IROperator.h:356
Halide::Internal::match_types_bitwise
void match_types_bitwise(Expr &a, Expr &b, const char *op_name)
Asserts that both expressions are integer types and are either both signed or both unsigned.
Halide::Internal::mod_imp< float >
float mod_imp< float >(float a, float b)
Definition: IROperator.h:303
Halide::Internal::raise_to_integer_power
Expr raise_to_integer_power(Expr a, int64_t b)
Raise an expression to an integer power by repeatedly multiplying it by itself.
Halide::Internal::make_signed_integer_overflow
Expr make_signed_integer_overflow(Type type)
Construct a unique signed_integer_overflow Expr.
Halide::Internal::is_const
bool is_const(const Expr &e)
Is the expression either an IntImm, a FloatImm, a StringImm, or a Cast of the same,...
Halide::Internal::remove_likelies
Expr remove_likelies(const Expr &e)
Return an Expr that is identical to the input Expr, but with all calls to likely() and likely_if_inne...
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::operator>=
auto operator>=(const Other &a, const GeneratorParam< T > &b) -> decltype(a >=(T) b)
Greater than or equal comparison between GeneratorParam<T> and any type that supports operator>= with...
Definition: Generator.h:1105
Halide::log
Expr log(Expr x)
Return the logarithm of a floating-point expression.
Halide::operator>>
Expr operator>>(Expr x, Expr y)
Shift the bits of an integer value right.
Halide::ceil
Expr ceil(Expr x)
Return the least whole number greater than or equal to a floating-point expression.
Halide::widen_right_add
Expr widen_right_add(Expr a, Expr b)
Below is a collection of intrinsics for fixed-point programming.
Halide::rounding_shift_right
Expr rounding_shift_right(Expr a, Expr b)
Compute saturating_narrow(widening_add(a, (1 << max(b, 0)) / 2) >> b).
Halide::memoize_tag
HALIDE_NO_USER_CODE_INLINE Expr memoize_tag(Expr result, Args &&...args)
Control the values used in the memoization cache key for memoize.
Definition: IROperator.h:1407
Halide::fast_log
Expr fast_log(const Expr &x)
Fast approximate cleanly vectorizable log for Float(32).
Halide::count_leading_zeros
Expr count_leading_zeros(Expr x)
Count the number of leading zero bits in an expression.
Halide::reinterpret
Expr reinterpret(Type t, Expr e)
Reinterpret the bits of one value as another type.
Halide::saturating_add
Expr saturating_add(Expr a, Expr b)
Compute saturating_narrow(widen(a) + widen(b))
Halide::operator==
auto operator==(const Other &a, const GeneratorParam< T > &b) -> decltype(a==(T) b)
Equality comparison between GeneratorParam<T> and any type that supports operator== with T.
Definition: Generator.h:1131
Halide::fast_cos
Expr fast_cos(const Expr &x)
Halide::operator*=
Expr & operator*=(Expr &a, Expr b)
Modify the first expression to be the product of two expressions, without changing its type.
Halide::random_uint
Expr random_uint(Expr seed=Expr())
Return a random variable representing a uniformly distributed unsigned 32-bit integer.
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::fract
Expr fract(const Expr &x)
Return the fractional part of a floating-point expression.
Halide::halving_add
Expr halving_add(Expr a, Expr b)
Compute narrow((widen(a) + widen(b)) / 2)
Halide::operator-=
Expr & operator-=(Expr &a, Expr b)
Modify the first expression to be the difference of two expressions, without changing its type.
Halide::operator<
auto operator<(const Other &a, const GeneratorParam< T > &b) -> decltype(a<(T) b)
Less than comparison between GeneratorParam<T> and any type that supports operator< with T.
Definition: Generator.h:1092
Halide::widening_shift_right
Expr widening_shift_right(Expr a, Expr b)
Compute widen(a) >> b.
Halide::operator*
auto operator*(const Other &a, const GeneratorParam< T > &b) -> decltype(a *(T) b)
Multiplication between GeneratorParam<T> and any type that supports operator* with T.
Definition: Generator.h:1040
Halide::strict_float
Expr strict_float(const Expr &e)
Makes a best effort attempt to preserve IEEE floating-point semantics in evaluating an expression.
Halide::trunc
Expr trunc(Expr x)
Return the integer part of a floating-point expression.
Halide::halving_sub
Expr halving_sub(Expr a, Expr b)
Compute narrow((widen(a) - widen(b)) / 2)
Halide::operator||
auto operator||(const Other &a, const GeneratorParam< T > &b) -> decltype(a||(T) b)
Logical or between between GeneratorParam<T> and any type that supports operator|| with T.
Definition: Generator.h:1174
Halide::acosh
Expr acosh(Expr x)
Return the hyperbolic arccosine of a floating-point expression.
Halide::fast_inverse
Expr fast_inverse(Expr x)
Fast approximate inverse for Float(32).
Halide::target_arch_is
Expr target_arch_is(Target::Arch arch)
Return a boolean Expr for the corresponding field of the Target being used during lowering; they can ...
Halide::asin
Expr asin(Expr x)
Return the arcsine of a floating-point expression.
Halide::rounding_shift_left
Expr rounding_shift_left(Expr a, Expr b)
Compute saturating_narrow(widening_add(a, (1 >> min(b, 0)) / 2) << b).
Halide::operator-
auto operator-(const Other &a, const GeneratorParam< T > &b) -> decltype(a -(T) b)
Subtraction between GeneratorParam<T> and any type that supports operator- with T.
Definition: Generator.h:1027
Halide::clamp
Expr clamp(Expr a, const Expr &min_val, const Expr &max_val)
Clamps an expression to lie within the given bounds.
Halide::hypot
Expr hypot(const Expr &x, const Expr &y)
Return the square root of the sum of the squares of two floating-point expressions.
Halide::popcount
Expr popcount(Expr x)
Count the number of set bits in an expression.
Halide::target_natural_vector_size
Expr target_natural_vector_size(Type t)
Return the natural vector width for the given Type for the Target being used during lowering; this ca...
Halide::saturating_sub
Expr saturating_sub(Expr a, Expr b)
Compute saturating_narrow(widen(a) - widen(b))
Halide::gather
Expr gather(const std::vector< Expr > &args)
Halide::print_when
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.
Halide::widening_shift_left
Expr widening_shift_left(Expr a, Expr b)
Compute widen(a) << b.
Halide::pow
Expr pow(Expr x, Expr y)
Return one floating point expression raised to the power of another.
Halide::operator&
Expr operator&(Expr x, Expr y)
Return the bitwise and of two expressions (which need not have the same type).
Halide::operator!
auto operator!(const GeneratorParam< T > &a) -> decltype(!(T) a)
Not operator for GeneratorParam.
Definition: Generator.h:1246
Halide::lerp
Expr lerp(Expr zero_val, Expr one_val, Expr weight)
Linear interpolate between the two values according to a weight.
Halide::atan2
Expr atan2(Expr y, Expr x)
Return the angle of a floating-point gradient.
Halide::random_float
Expr random_float(Expr seed=Expr())
Return a random variable representing a uniformly distributed float in the half-open interval [0....
Halide::sin
Expr sin(Expr x)
Return the sine of a floating-point expression.
Halide::unsafe_promise_clamped
Expr unsafe_promise_clamped(const Expr &value, const Expr &min, const Expr &max)
Create an Expr that that promises another Expr is clamped but do not generate code to check the asser...
Halide::rounding_halving_add
Expr rounding_halving_add(Expr a, Expr b)
Compute narrow((widen(a) + widen(b) + 1) / 2)
Halide::extract_bits
Expr extract_bits(Type t, const Expr &e, const Expr &lsb)
Extract a contiguous subsequence of the bits of 'e', starting at the bit index given by 'lsb',...
Halide::concat_bits
Expr concat_bits(const std::vector< Expr > &e)
Given a number of Exprs of the same type, concatenate their bits producing a single Expr of the same ...
Halide::mux
Expr mux(const Expr &id, const std::initializer_list< Expr > &values)
Oftentimes we want to pack a list of expressions with the same type into a channel dimension,...
Halide::cosh
Expr cosh(Expr x)
Return the hyperbolic cosine of a floating-point expression.
Halide::operator<<
std::ostream & operator<<(std::ostream &stream, const Expr &)
Emit an expression on an output stream (such as std::cout) in human-readable form.
Halide::Int
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
Definition: Type.h:539
Halide::acos
Expr acos(Expr x)
Return the arccosine of a floating-point expression.
Halide::fast_exp
Expr fast_exp(const Expr &x)
Fast approximate cleanly vectorizable exp for Float(32).
Halide::widening_add
Expr widening_add(Expr a, Expr b)
Compute widen(a) + widen(b).
Halide::target_os_is
Expr target_os_is(Target::OS os)
Halide::cos
Expr cos(Expr x)
Return the cosine of a floating-point expression.
Halide::operator+
auto operator+(const Other &a, const GeneratorParam< T > &b) -> decltype(a+(T) b)
Addition between GeneratorParam<T> and any type that supports operator+ with T.
Definition: Generator.h:1014
Halide::min
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:603
Halide::exp
Expr exp(Expr x)
Return the exponential of a floating-point expression.
Halide::widen_right_mul
Expr widen_right_mul(Expr a, Expr b)
Compute a * widen(b).
Halide::absd
Expr absd(Expr a, Expr b)
Return the absolute difference between two values.
Halide::operator&&
auto operator&&(const Other &a, const GeneratorParam< T > &b) -> decltype(a &&(T) b)
Logical and between between GeneratorParam<T> and any type that supports operator&& with T.
Definition: Generator.h:1157
Halide::fast_sin
Expr fast_sin(const Expr &x)
Fast vectorizable approximation to some trigonometric functions for Float(32).
Halide::undef
Expr undef(Type t)
Return an undef value of the given type.
Halide::fast_pow
Expr fast_pow(Expr x, Expr y)
Fast approximate cleanly vectorizable pow for Float(32).
Halide::operator%
auto operator%(const Other &a, const GeneratorParam< T > &b) -> decltype(a %(T) b)
Modulo between GeneratorParam<T> and any type that supports operator% with T.
Definition: Generator.h:1066
Halide::round
Expr round(Expr x)
Return the whole number closest to a floating-point expression.
Halide::select
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...
Halide::count_trailing_zeros
Expr count_trailing_zeros(Expr x)
Count the number of trailing zero bits in an expression.
Halide::scatter
Expr scatter(const std::vector< Expr > &args)
Scatter and gather are used for update definition which must store multiple values to distinct locati...
Halide::operator<=
auto operator<=(const Other &a, const GeneratorParam< T > &b) -> decltype(a<=(T) b)
Less than or equal comparison between GeneratorParam<T> and any type that supports operator<= with T.
Definition: Generator.h:1118
Halide::rounding_mul_shift_right
Expr rounding_mul_shift_right(Expr a, Expr b, Expr q)
Compute saturating_narrow(rounding_shift_right(widening_mul(a, b), q))
Halide::random_int
Expr random_int(Expr seed=Expr())
Return a random variable representing a uniformly distributed 32-bit integer.
Halide::mod_round_to_zero
Expr mod_round_to_zero(Expr x, Expr y)
Compute the remainder of dividing two integers, when division is rounding toward zero.
Halide::operator/=
Expr & operator/=(Expr &a, Expr b)
Modify the first expression to be the ratio of two expressions, without changing its type.
Halide::widening_mul
Expr widening_mul(Expr a, Expr b)
Compute widen(a) * widen(b).
Halide::operator>
auto operator>(const Other &a, const GeneratorParam< T > &b) -> decltype(a >(T) b)
Greater than comparison between GeneratorParam<T> and any type that supports operator> with T.
Definition: Generator.h:1079
Halide::is_nan
Expr is_nan(Expr x)
Returns true if the argument is a Not a Number (NaN).
Halide::asinh
Expr asinh(Expr x)
Return the hyperbolic arcsinhe of a floating-point expression.
Halide::sqrt
Expr sqrt(Expr x)
Return the square root of a floating-point expression.
Halide::sinh
Expr sinh(Expr x)
Return the hyperbolic sine of a floating-point expression.
Halide::atan
Expr atan(Expr x)
Return the arctangent of a floating-point expression.
Halide::operator|
Expr operator|(Expr x, Expr y)
Return the bitwise or of two expressions (which need not have the same type).
Halide::operator!=
auto operator!=(const Other &a, const GeneratorParam< T > &b) -> decltype(a !=(T) b)
Inequality comparison between between GeneratorParam<T> and any type that supports operator!...
Definition: Generator.h:1144
Halide::target_bits
Expr target_bits()
Return the bit width of the Target used during lowering; this can be useful in writing library code w...
Halide::cast
Internal::ConstantInterval cast(Type t, const Internal::ConstantInterval &a)
Cast operators for ConstantIntervals.
Halide::require
Expr require(Expr condition, const std::vector< Expr > &values)
Create an Expr that that guarantees a precondition.
Halide::is_inf
Expr is_inf(Expr x)
Returns true if the argument is Inf or -Inf.
Halide::is_finite
Expr is_finite(Expr x)
Returns true if the argument is a finite value (ie, neither NaN nor Inf).
Halide::tanh
Expr tanh(Expr x)
Return the hyperbolic tangent of a floating-point expression.
Halide::likely_if_innermost
Expr likely_if_innermost(Expr e)
Equivalent to likely, but only triggers a loop partitioning if found in an innermost loop.
Halide::atanh
Expr atanh(Expr x)
Return the hyperbolic arctangent of a floating-point expression.
Halide::tan
Expr tan(Expr x)
Return the tangent of a floating-point expression.
Halide::saturating_cast
Internal::ConstantInterval saturating_cast(Type t, const Internal::ConstantInterval &a)
Halide::fast_inverse_sqrt
Expr fast_inverse_sqrt(Expr x)
Fast approximate inverse square root for Float(32).
Halide::print
Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
Halide::mul_shift_right
Expr mul_shift_right(Expr a, Expr b, Expr q)
Compute saturating_narrow(shift_right(widening_mul(a, b), q))
Halide::operator/
auto operator/(const Other &a, const GeneratorParam< T > &b) -> decltype(a/(T) b)
Division between GeneratorParam<T> and any type that supports operator/ with T.
Definition: Generator.h:1053
Halide::operator+=
Expr & operator+=(Expr &a, Expr b)
Modify the first expression to be the sum of two expressions, without changing its type.
Halide::abs
Expr abs(Expr a)
Returns the absolute value of a signed integer or floating-point expression.
Halide::widen_right_sub
Expr widen_right_sub(Expr a, Expr b)
Compute a - widen(b).
Halide::max
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:606
Halide::floor
Expr floor(Expr x)
Return the greatest whole number less than or equal to a floating-point expression.
Halide::div_round_to_zero
Expr div_round_to_zero(Expr x, Expr y)
Divide two integers, rounding towards zero.
Halide::widening_sub
Expr widening_sub(Expr a, Expr b)
Compute widen(a) - widen(b).
Halide::likely
Expr likely(Expr e)
Expressions tagged with this intrinsic are considered to be part of the steady state of some loop wit...
Halide::operator~
Expr operator~(Expr x)
Return the bitwise not of an expression.
Halide::erf
Expr erf(const Expr &x)
Evaluate the error function erf.
Halide::target_has_feature
Expr target_has_feature(Target::Feature feat)
Halide::operator^
Expr operator^(Expr x, Expr y)
Return the bitwise xor of two expressions (which need not have the same type).
uint64_t
unsigned __INT64_TYPE__ uint64_t
Definition: runtime_internal.h:23
int64_t
signed __INT64_TYPE__ int64_t
Definition: runtime_internal.h:22
int32_t
signed __INT32_TYPE__ int32_t
Definition: runtime_internal.h:24
uint8_t
unsigned __INT8_TYPE__ uint8_t
Definition: runtime_internal.h:29
uint16_t
unsigned __INT16_TYPE__ uint16_t
Definition: runtime_internal.h:27
uint32_t
unsigned __INT32_TYPE__ uint32_t
Definition: runtime_internal.h:25
int16_t
signed __INT16_TYPE__ int16_t
Definition: runtime_internal.h:26
int8_t
signed __INT8_TYPE__ int8_t
Definition: runtime_internal.h:28
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:258
Halide::Internal::BufferBuilder
A builder to help create Exprs representing halide_buffer_t structs (e.g.
Definition: IROperator.h:228
Halide::Internal::BufferBuilder::device
Expr device
Definition: IROperator.h:230
Halide::Internal::BufferBuilder::host_dirty
Expr host_dirty
Definition: IROperator.h:234
Halide::Internal::BufferBuilder::dimensions
int dimensions
Definition: IROperator.h:232
Halide::Internal::BufferBuilder::type
Type type
Definition: IROperator.h:231
Halide::Internal::BufferBuilder::host
Expr host
Definition: IROperator.h:230
Halide::Internal::BufferBuilder::strides
std::vector< Expr > strides
Definition: IROperator.h:233
Halide::Internal::BufferBuilder::shape_memory
Expr shape_memory
Definition: IROperator.h:229
Halide::Internal::BufferBuilder::build
Expr build() const
Halide::Internal::BufferBuilder::device_interface
Expr device_interface
Definition: IROperator.h:230
Halide::Internal::BufferBuilder::device_dirty
Expr device_dirty
Definition: IROperator.h:234
Halide::Internal::BufferBuilder::extents
std::vector< Expr > extents
Definition: IROperator.h:233
Halide::Internal::BufferBuilder::mins
std::vector< Expr > mins
Definition: IROperator.h:233
Halide::Internal::BufferBuilder::buffer_memory
Expr buffer_memory
Definition: IROperator.h:229
Halide::Internal::Stmt
A reference-counted handle to a statement node.
Definition: Expr.h:427
Halide::Internal::all_are_convertible
Definition: Util.h:263
Halide::Internal::all_are_printable_args
Definition: IROperator.h:350
Halide::Internal::cond
Definition: Generator.h:380
Halide::Internal::is_printable_arg
Definition: IROperator.h:344
Halide::Internal::is_printable_arg::value
static constexpr bool value
Definition: IROperator.h:345
Halide::Internal::meta_and
Definition: Util.h:251
Halide::Target::Feature
Feature
Optional features a target can have.
Definition: Target.h:84
Halide::Target::Arch
Arch
The architecture used by the target.
Definition: Target.h:39
Halide::Target::OS
OS
The operating system used by the target.
Definition: Target.h:23
Halide::Type
Types in the halide type system.
Definition: Type.h:281
Halide::Type::is_int
HALIDE_ALWAYS_INLINE bool is_int() const
Is this type a signed integer type?
Definition: Type.h:433
Halide::Type::is_float
HALIDE_ALWAYS_INLINE bool is_float() const
Is this type a floating point type (float or double).
Definition: Type.h:421
Halide::float16_t
Class that provides a type that implements half precision floating point (IEEE754 2008 binary16) in s...
Definition: Float16.h:17