Herbgrind analyzes binaries to find inaccurate floating point expressions. The binaries can come from anywhere-C source, Fortran source, even unknown origins. This tutorial runs Herbgrind on the benchmark programs that Herbgrind ships with.
Herbgrind ships test binaries in its
directory. You can build them with:
make -C bench all
Let's analyze the
diff-roots-simple.out binary that
you just compiled. Run Herbgrind on that binary with:
This should produce output that looks like this:
==16725== Herbgrind, a valgrind tool for Herbie ==16725== ==16725== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==16725== Command: bench/diff-roots-simple.out ==16725== 1.578592e-07 ==16725== Writing report out to bench/diff-roots-simple.out.gh
The printed value,
1.578592e-07, is printed by
diff-roots-simple.out binary. Herbgrind writes its
results to the named
bench/diff-roots-simple.gh. This file
contains one record for each operation; the only operation found
(FPCore () :type binary64 (- (sqrt (+ 1.000000 10000000000000.000000)) (sqrt 10000000000000.000000))) subtraction in main at diff-roots-simple.c:12 (address 400A00) 43.129555 bits average error 43.129555 bits max error Aggregated over 1 instances
The first line gives the expression inaccurately evaluated, and
the second line gives its location. That line
diff-roots-simple.c is actually:
y = sqrt(x + 1) - sqrt(x);
Since this line of code is run only once, Herbgrind doesn't know
x is intended to be a variable, and instead
inlines its value. In a slightly more complicated
diff-roots.c, this code is executed in a
loop with different values for
x, so Herbgrind will
report it as a variable.
The next three lines of the output give the error incurred by the inaccurate computation: 43.1 bits of error over 1 instance of computing that expression.
While running on
found inaccurate computations not only
diff-roots-simple.out but also in several GNU
library calls. Herbgrind has a feature to avoid tracking floating
point operations in libraries and other code not within your
control by adding instrumentation to your source code.
Simply surround the numerically-interesting parts of your
computation in the
// initialization code ... HERBGRIND_BEGIN(); // numerical code ... HERBGRIND_END(); // cleanup code ...
diff-roots-simple.c example does this on lines
11 and 13. You can then run Herbgrind with
--start-off flag, which tells Herbgrind not to
begin analyzing floating point operations until it sees
./herbgrind --start-off bench/diff-roots-simple.out
The report file now contains only the inaccurate expression described before, and no library computations.
regions can be sprinkled anywhere in your source code; it's common
to use them to start Herbgrind only after initializing your
program and before cleaning up and outputting results. Herbgrind
can be turned on and off multiple times.