HIR vs Calyx

What are the main conceptual differences between the two. Is one more expressive than the other? Do they achieve the same thing in different ways. I have recently began exploring the literature around HLS intermediate language and I would like to hear other people’s thoughts

Hi, I am the author of HIR. Below is my understanding of the differences and similarities of the two IRs:

  • Calyx IR does not capture schedules explicitly (as far as I know) while HIR does. HIR is designed to represent the circuit after scheduling is done.
  • Calyx can represent dynamically scheduled circuits (handshaking) but HIR is designed for statically scheduled circuits only.
  • In calyx, control flow is separated from data flow, hir has a unified representation.
  • Calyx does not have explicit support for loop/function pipelining (as per the Calyx paper). HIR supports pipelining. However, calyx can still pipeline circuits using its parallel regions.

There is overlap between the two IRs. For instance, though calyx does not capture the schedule explicitly, its compiler can generate statically scheduled circuits if all the operator delays are known.

Both IRs are a work in progress and may have even more overlap in the future. For instance, I am working on improving HIR’s support for dynamic interfaces (external dram) while there is ongoing work towards adding pipelining support for calyx (as far as I know).

1 Like

Hey, lead on the Calyx project here. I think @kingshuk1000 has a pretty reasonable high-level summary with the following clarifications:

  • “Schedules” is a pretty overloaded term in compiler literature. Just to clarify, Calyx captures the control flow of the program explicitly which allows for optimizations that require both structural information (which wire is connected to which hardware component) and control flow information (which sub-circuits are executed in parallel).
  • Calyx has latency-insensitive interfaces by default and treats latency-sensitivity as an optimization. This means every circuit is guaranteed to be compilable to hardware and when extra information is provided, better, latency-sensitive circuitry can be generated.
  • The separation between control flow and data flow is ornamental and doesn’t really affect what kinds of optimizations you can do.
  • Calyx does not have an explicit pipeline operate, instead, pipelines can be represented using the parallel operator and invokes (which have been added since the paper was published).

Calyx is already a part of the CIRCT project as a dialect and has compilation paths from the scf dialect and static logic. The former is used to generate dynamic circuits while the latter is used to generate pipelined loops in Calyx.

If you’re curious about using Calyx/CIRCT, please feel free to open a new discussion thread and taking a look at the website.

I already had a look into the various presentations and material from the CIRCT effort. It is just that I am new to compilers and hardware description languages terminology and concepts that I don’t fully understand the problems associated with it, or what kind of information must be encoded into the various levels of abstraction. It also doesn’t help that sometimes the terminology is “polluted” (for marketing) making it harder make associations and comparison between the different papers in the literature. Do you have any suggestions as to what materials to read to improve my understanding? Also would it be ok to ask follow-up questions regarding your projects once I understand them better?

Also thank you for your replies! @kingshuk1000, @rachitnigam

Yup, feel free to ask more questions. I think the questions about what information needs to be encoded in an IR is a tricky design question with no clear cut answer. Each IR makes its own decisions about what to encode depending on the kinds of optimizations that need to occur at that level. It is usually a failing proposition to build “one IR for all optimizations” because different levels of abstractions support different optimization.

The most clear-cut example of such a differences between HIR and Calyx are Calyx choice to avoid being tied to specific timing behavior to allow broader categories of architectural optimizations but loosing the ability to do things like verify pipelining (which I think HIR does).

For the current C++ → Calyx flow, a different IR handles construction and optimization of pipelines which occurs at a higher level than Calyx allowing Calyx to focus on different kinds of optimizations.