Replies: 4 comments 17 replies
-
Nice, I definitely agree with the generator aspect. FWIW, the In #463, I tried taking the LUT approach, but wasn't getting very accurate numbers, hence moving to the TS expansion. I don't recall the why this isn't working, but may be a good starting place. One question about the LUT implementation that we've discussed before, but should put concretely. Where do you see LUTs living in a Calyx program? SystemVerilog takes a reg out;
wire [1:0] in;
always @(in)
case(in)
2'b00 : out = 0;
2'b01 : out = 0;
2'b10 : out = 1;
2'b11 : out = 1;
endcase Our options in Calyx:
However, this seems like a patch for what we really want:
|
Beta Was this translation helpful? Give feedback.
-
The second question I have is testing. We can write simple corner case tests, but I don't think that will always be sufficient. It would be interesting to set up some comparison with an "industry-standard" version. For example, LLVM libc tests their Math library against the battle-hardened GCC version. Is their an equivalent battle-hardened library for fixed point operations to validate the Calyx |
Beta Was this translation helpful? Give feedback.
-
I was trying to add on to this project to get an ln(x) generator that would work similarly to the (already implemented) e^x generator. Once we get this, then we would pretty easily be able to compute logs and exponents for any power and any base. There are good, relatively simple, ways to approximate ln(x). The main problem is division. Currently the way the |
Beta Was this translation helpful? Give feedback.
-
Just appending one more idea to this one: consider automatically searching the space of alternative implementations for a given math expression, as suggested in #1226 (comment) and subsequent comments. (Perhaps using egraphs??) The overall message for the project would be that a "libm for hardware" must fundamentally look different than a libm for software. You don't just want a single inventory of math primitives; you want a generator that can implement many different low-level strategies for accomplishing parts of an expression that uses libm functions. |
Beta Was this translation helpful? Give feedback.
-
I promised a while back to jot down some thoughts and links about the idea of generating numerical functions for Calyx programs.
The idea would be to write a Calyx "frontend" that generates implementations of elementary mathematical functions. It would roughly want to cover the set of functions in C's libm: that means stuff like
exp
,log2
,tanh
,sqrt
, that sort of thing. Having these functions is important because lots of realistic accelerators really, really need to use math functions. For an example, our Relay frontend very quickly ran into a need for exponentiation to implement the softmax operator: see #463, #490, #369, etc.The reason this would need to be a generator rather than a single, fixed-function library is twofold:
A good place to start reading about generating elementary numerical function implementations (for software, not hardware) would be the very recent RLIBM paper. There's also a nice blog post about the project. However, keep this in mind when reading about that work: we should not strive for correct rounding as RLIBM does. That's a very high bar that requires complex machinery to get right; we should use a much more standard approach to get "roughly good enough" implementations at various accuracy levels. I recommend the paper because it does a good job of surveying the status quo of best-effort, not-correctly-rounded implementations—it's that status quo that we should emulate.
I also recommend reading about (i.e., googling around for papers and such about) the Remez algorithm. It's an example of a practical algorithm for finding a polynomial approximation to a given function. A great place to start, for instance, would be the lolremez tool that uses it to generate polynomial approximations for arbitrary input functions. We could do far worse in v1.0 of this project than essentially porting lolremez from generating C to generating Calyx.
However, I think we should start at an even more basic level: let's just generate look-up tables! That is, let's build a generator whose input is a specification of the function to generate (in whatever representation we can come up with), a value range, and a number of table entries. It should also take a numerical format as input. It produces, as output, Calyx program that just looks up the answer in an appropriately-sized ROM. Having this basic LUT-based approach implemented will be a truly excellent minimum viable product: it will be far better than nothing (which we currently have), and it will be a great basis for comparison to empirically demonstrate how more advanced techniques (i.e., polynomial approximation) can outperform it as a baseline.
Beta Was this translation helpful? Give feedback.
All reactions