calyxir / calyx

Intermediate Language (IL) for Hardware Accelerator Generators
https://calyxir.org
MIT License
469 stars 46 forks source link

Optimize fixed-point conversion #1315

Open rachitnigam opened 1 year ago

rachitnigam commented 1 year ago

Writing some some investigating I did in the json_to_dat code we have for converting floating point numbers to fixed point. Currently, conversion to fixed-point is a very big overhead when working with big input files. For example, when converting the lenet input data file, we take almost 25 seconds to convert the largest data array.

Profiling points to this line of code: https://github.com/cucapra/calyx/blob/54c68896bb7aa1d7138d4cff05866052b1dbc62d/fud/fud/stages/verilator/numeric_types.py#L173

The Fraction class in python attempts to convert the floating-point number into a rational by computing the numerator and denominator. Unfortunately, this computation is very slow because it attempts to provide a precise answer. Another code path exacerbates the problem: https://github.com/cucapra/calyx/blob/54c68896bb7aa1d7138d4cff05866052b1dbc62d/fud/fud/stages/verilator/json_to_dat.py#L135-L143

The code attempts to convert the float into fixed and uses the exception thrown from conversion to decide whether to round the number. Exception-based control flow is a bad idea and we should instead check if the number needs rounding before calling the conversion method. A quick (incorrect) change to the code shows that we can get back 9 seconds by doing this.

Unfortunately this leaves a lot of performance on the table which cannot be recovered without substantial changes. Specifically, conversion to Fraction is always going to be slow. For example, a tight loop of converting random float numbers to fixed-point shows that we can convert 100,000 numbers in 15 seconds. The trend seems to hold if we use gmpy or fxpmath libraries.

On the other hand, rust's fixed library is faster–10,000,000 in 17 seconds. Unfortunately, something like googlenet, which is significantly larger, even this will probably not be fast enough. I wonder if there is a fundamentally faster way to convert to fixed-point...

Anyways, here is recommended course of action in order of increasing difficulty:

sampsyo commented 1 year ago

It's a good point that this data-conversion stuff could be better! With apologies for zooming out quite a bit, here are some thoughts I have been meaning to write down for a while:

rachitnigam commented 1 year ago

Another arbitrary precision lib in rust: https://www.malachite.rs/