calyx
calyx copied to clipboard
Calyx Level Statistics Pass
Just writing up a small idea that emerged during this week's meeting. It would be nice to have a primitive use/statistics pass at the Calyx level to determine total counts of components and could potentially become a resource use estimation pass.
Desiderata:
- Largest Mux generated = max(# of assignments to a port)
- Total number of muxed assignments
Heck yes! This would be super cool. I suppose v1.0 of this could produce a CSV file that looks roughly like:
component,count
main,1
std_mul,5
std_add,22
my_great_subcomponent,3
In other words, it would count the total number of instantiations of every component in a given program, primitive or otherwise. There would always be exactly one instantiation of the top-level component main, for example.
That would provide a good foundation for a more elaborate project where we actually try to estimate area (i.e., resource consumption for a particular backend).
In a recent synchronous meeting about Pollen, the occasionally-discussed desire for an easier route to resource estimation arose again. @priyasrikumar sounded interested in trying this out as a way to get more familiar with the Calyx compiler internals, which seems like a great idea and very timely to me. So, here is a little more detail on a simple trajectory I can imagine:
- v1.0: Just count the primitives, producing a simple CSV like the one illustrated above.
- v1.1: Consider adding primitive parameters to the CSV report. In particular, add a third column to the CSV output called
paramsor similar that disambiguates different instantiations of the same primitive with different attributes. For example, when a program initiates astd_mult_pipe(32)and astd_mult_pipe(16), those would show up as different lines in the output CSV, each with count 1. - v2.0: Memory size estimation. This would basically work as a post-processing pass on the CSV data produced from v1.1, and it would estimate the total number of bits occupied by all the memories in a program. For example,
std_mem_d1(32,8,4)is a memory consisting of eight 32-bit values, so that's 256 bits total. v2.0 would total all this up for all the memories and report the total number of bits. (Not bytes, because our memories can have odd-sized elements.) Maybe it would be good to break down the output by memory type:std_mem_*vs.seq_mem_*, and possibly includingstd_regas a third category. - v2.1: Invent some way to compare these estimates against Vivado's so we can tell how close we are.
- v3.0: Add cost models for non-memory components, somehow guessing the LUT and DSP occupancy from a Calyx program. Again, create a way to compare these estimates with Vivado's. We'll also want pluggable cost models, so we can estimate different quantities for different backend toolchains (ASIC or FPGA). Probably don't bother to be anywhere close to accurate on high-level Calyx programs; only consider fully lowered code. (Estimating the cost of guards is still a problem in this scenario.)
- v4.0 and beyond: Maybe try to estimate costs for high-level Calyx programs, before compilation? Not sure if that's useful. Also, consider trying to estimate critical paths, i.e., maximum clock period. That seems really hard but also really useful.
Anyway, for our proximate needs in Pollen, we should set our eyes on v2.0 above, which seems both achievable and really useful all on its own. Stuff after that is much more speculative/just for fun.
FWIW, I think the right way to think about implementing this would be by adding a backend, i.e., a sibling to our current verilog and mlir backends. This would let the compiler do any amount of lowering/optimization followed by a resource-estimation report, producing a CSV instead of an output program. But I dunno; it could also just be a pass and produce a file on the side. Not sure which is best.
@priyasrikumar would you consider this closed by the newest PR?
I didn't initially consider this closed due to v2.1 onward being unimplemented. However, after our discussion about the backend, I suppose we can consider this closed and make a separate issue for further development?
Yeah, I think we can close this one because we've done the big stuff!! I say we leave it here until we have a need at some point for "short circuiting" Vivado and guessing what it will say.
Alright! Closed by https://github.com/cucapra/calyx/pull/1372!