Live data from Hacker News

Herbie: Automatically improve imprecise floating point formulas

herbie.uwplse.org

11–20 of 47 posts

Re: Herbie: Automatically improve imprecise floating point formulas

#12

How useful is this when you are using numbers in a reasonable range, like 10^-12 to 10^12? Generally I try to scale my numbers to be in this range, whether by picking the right units or scaling constraints and objectives when doing nonlinear programming/ optimization. Like looking at this example, https://herbie.uwplse.org/demo/b070b371a661191752fe37ce0321c... It is claimed that for the function f(x) =sqrt(x+1) -1 Ac…

The precondition on the link you shared has -1 <= x && x <= 1, so 99 is way outside of that range. But even so, testing for x=1, which is supposed to be inside that range, 0.5 doesn't seem tolerably close to 0.4142.

I have a suspicion that the accuracy number is the mean of accuracies over all valid floats in the range (or something approximating that), which is going to be weighted towards zero where the accuracy is higher, and perhaps where sqrt near 1 has some artefacts.

Re: Herbie: Automatically improve imprecise floating point formulas

#14

Some trivial cases produce... interesting results. For x in [−1.79e308, 1.79e308]: Initial Program: 100.0% accurate, 1.0× speedup def code(x): return math.sqrt((x + 1.0)) Alternative 1: 67.5% accurate, 5.6× speedup def code(x): return 1.0

That does make sense, because a half of all available fp numbers are less than 1 in their magnitude. In particular there should be a plenty of numbers x such that |x| << 1 so x + 1 ~= 1; in fact, the proportion should be just shy of 50%.

Re: Herbie: Automatically improve imprecise floating point formulas

#15

Some trivial cases produce... interesting results. For x in [−1.79e308, 1.79e308]: Initial Program: 100.0% accurate, 1.0× speedup def code(x): return math.sqrt((x + 1.0)) Alternative 1: 67.5% accurate, 5.6× speedup def code(x): return 1.0

That does make sense, because a half of all available fp numbers are less than 1 in their magnitude. In particular there should be a plenty of numbers x such that |x| << 1 so x + 1 ~= 1; in fact, the proportion should be just shy of 50%.

But I guess using the density distribution of floating points is rarely useful in a problem. Your actual distribution will almost surely be way different. Imo, the tool presented here should provide a way to manually provide a custom density function (with some common presets like uniform and normal distributions).

Re: Herbie: Automatically improve imprecise floating point formulas

#17

Some trivial cases produce... interesting results. For x in [−1.79e308, 1.79e308]: Initial Program: 100.0% accurate, 1.0× speedup def code(x): return math.sqrt((x + 1.0)) Alternative 1: 67.5% accurate, 5.6× speedup def code(x): return 1.0

That does make sense, because a half of all available fp numbers are less than 1 in their magnitude. In particular there should be a plenty of numbers x such that |x| << 1 so x + 1 ~= 1; in fact, the proportion should be just shy of 50%.

That is indeed one of the problems with IEEE floats. There are only 10^80 atoms in the universe, and a Planck length is 1^-60th of the radius of the universe. But 64-bit floats have an absurd range of over 10^±300! Worse than that, notice that there are as many bit patterns in the never-used range between 10^300 and 10^301 as there are in the super-important range between 1 and 10! Super wasteful. Not to mention the quadrillions of values reserved to represent "NaN"...

This is one of the problems that alternative formats such as the Posit aim to solve. It's quite interesting: I've got an implementation in rust here if you want to play with it https://github.com/andrepd/posit-rust

Re: Herbie: Automatically improve imprecise floating point formulas

#19
I posted this and it picked up steam over night, so I thought I'd add how I'm using it:

I work on 3D/4D math in F#. As part of the testing strategy for algorithms, I've set up a custom agent with an F# script that instruments Roslyn to find FP and FP-in-loop hotspots across the codebase.

The agent then reasons through the implementation and writes core expressions into an FPCore file next to the existing tests, running several passes, refining the pres based on realistic caller input. This logs Herbie's proposed improvements as output FPCore transformations. The agent then reasons through solutions (which is required, Herbie doesn't know algorithm design intent, see e.g. this for a good case study: https://pavpanchekha.com/blog/herbie-rust.html), and once convinced of a gap, creates additional unit tests and property tests (FsCheck/QuickCheck) to prove impact. Then every once in a while I review a batch to see what's next.

Generally there are multiple types of issues that can be flagged:

a) Expression-level imprecision over realistic input ranges: this is Herbie's core strength. Usually this catches "just copied the textbook formula" instance of naive math. Cancellation, Inf/NaN propagation, etc. The fixes are consistently using fma for accumulation, biggest-factor scaling to prevent Inf, hypot use, etc.

b) Ill-conditioned algorithms. Sometimes the text books lie to you, and the algorithms themselves are unfit for purpose, especially in boundary regions. If there are multiple expressions that have a c) Round-off, accumulation errors. This is more a consequence of agent reasoning, but often happens after an apparent "100% -> 100%" pass. The agent is able to, via failing tests, identify parts of an algorithm that can benefit from upgrading the context to e.g. double-word arithmetic for additional precision.

Post reply on HN