-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Debugging Tips
HL_TRACE=1 prints out the boundaries of all realizations of Funcs. (Inlined Funcs don't really have boundaries.)
Higher values of HL_TRACE start to print the loads and stores too.
You can also call Func::trace_realizations to get a printf that displays the boundaries for a particular func.
You can wrap a print around an Expr to print its value at runtime, e.g say you think b is taking on bad values in the following Func definition:
f(x) = a + b;
You could rewrite this to:
f(x) = a + print(b, " <- b has this value when x is ", x);
print returns the first argument, and prints all the arguments as a side-effect. The arguments may be of type Expr, std::string, const char *, int, or float.
You can also conditionally print:
f(x) = a + print_when(b < 0, b, " b was not supposed to be negative! It happened at x = ", x);
print_when returns the second argument. When the first argument is true, it prints all the arguments as a side-effect.
You can use Func::compile_to_lowered_stmt to compile a Halide pipeline to human-readable imperative psuedo-code that includes all the effects of scheduling. E.g:
#include <Halide.h>
using namespace Halide;
int main(int argc, char **argv) {
Func f;
Var x, y;
f(x, y) = x+y;
f.vectorize(x, 4).unroll(x, 2).parallel(y);
f.compile_to_lowered_stmt("f.html", HTML);
return 0;
}
produces this output
This functionality also has a variant which simplifies the lowered pseudocode, given concrete output bounds and other parameter values, called [Func::compile_to_simplified_lowered_stmt](http://halide-lang.org/docs/class_halide_1_1_func.html#a052a6f0c9ef689593bad537b4e0a37b8)
. This does not reflect the exact code which is generated during compilation, which normally supports arbitrary output bounds and parameter sizes, but it can further simplify the basic structure of the pseudocode for easier comprehension. It is used just like the example above, but with additional arguments to specify concrete parameter values for simplification:
//...
// dump simplified pseudocode, assuming a 256x224 output, like f.realize(256, 224)
f.compile_to_simplified_lowered_stmt("f-simplified.html", 256, 224, HTML);
// or, given a function with more parameters...
Param<int> p;
Func g;
g(x,y) = f(p*x, p*y);
// ...specify concrete values for those parameters, as well:
std::map<std::string, Expr> params;
params[p.name()] = 2;
g.compile_to_simplified_lowered_stmt("g-simplified.html", 256, 224, params, HTML);
// and the full program, for comparison:
g.compile_to_lowered_stmt("g.html", HTML);