Calyx Opt Spring 2024 Lab Notebook #1848
Replies: 9 comments 26 replies
-
Hello! Just a brief overview of what I've been focusing on since I started my mini-pass a couple weeks ago: I got started by learning a bit of Rust syntax and about the whole ownership model, which was pretty new and definitely a bit of a learning curve. I still run into borrow-checker issues, but they are dramatically fewer than when I started. I had also heard that Rust has a lot of functional features, and coming in with a little bit of an OCaml perspective, I was looking forward to using them -- I wasn't disappointed! I started working on my unused-port-removal pass, which follows this (#1200) issue. I had a bit of trouble learning the IR for Calyx, since there were certain ideas that didn't directly follow from Calyx syntax. In particular, I spoke at length with @calebmkim about the Visitor trait and how it represents and traverses components, and the Component struct, which was a bit confusing with all of its nested fields. However, after working step-by-step and getting information from only the necessary parts of the IR, I started also getting familiar with that, and saw how closely it resembled Calyx programs. So far, I built a HashMap that maps each component to its used ports. Then, I took the set difference between all of a components ports (defined in its signature) and its used ports, and got a set of unused ports. I then iterated through these unused ports, and added an attribute @internal to them. The next step is to actually remove the ports. The code lives here: https://github.com/calyxir/calyx/blob/unused-port-removal/calyx-opt/src/passes/unused_port_removal.rs I made a couple assumptions that I'll definitely have to verify. Is it true that:
Thanks! |
Beta Was this translation helpful? Give feedback.
-
Hello! Apologies for the delay on updates. In the last week, Caleb and I were discussing exactly that question: which ports do we feel safe enough to remove (and, by association, how aggressive should we be in removing them)? In addition to those ports (as in your example, Rachit) where removing an unused port of A would make one of B's port unused, we were also considering how guards might play into this. I initially ran into quite a bit of confusion here, since I thought that if a guard within a component A uses one of A's ports p then, even though the outside world may not use p, we should still consider it to be "used" -- that snowballed into a bit of a crisis about what it means to "use" a port, but Caleb reassured me in our most recent meeting on Thursday that, if port p is used in a guard and is not used by the outside world, then p's presence in the guard is the same as a "low" signal. So, if I'd like to, I could extend the pass to remove these unused ports, and replace all of the port's uses in the guard with a n'b0 constant. Honestly, I think that'd be really cool! But, as cool as it would be to be super aggressive and also keep the intended "meaning" of the modules by using n'b0's, we were both wondering whether it was "worth it" in terms of overhead on a design. Is there a substantial resource wastage with keeping these unused ports around? Is it not possible to say, since a port could be passed through any number of gates before becoming a part of a guard? What's the "average case"? I think it'd still be very cool to do it (especially if there's no "upper bound" on wasted resources), and I've already gotten started. To be honest, I think the case where a port is unused by the outside world and is also not used in a guard internally is pretty rare, so if we don't do this, then is it possible that we'd be optimizing a kind of trivial case? If I get the green light, I'm hoping to have things done and tested by next weekend. Then, if possible, I'd love to discuss further plans as they come up! Thanks! Apologies again, I will be sure to be more timely with updates |
Beta Was this translation helpful? Give feedback.
-
Hello! This week was pretty cool, along with some gnarly head-butting against Rust's type system. Based on feedback, I indeed began by mapping out what it concretely means to get rid of unused ports. I took care of the trivial case pretty easily, which is: at each component, if there exist any unused ports in the signature of the component, then remove those from the signature. As we've mentioned, the tricky part came when I started trying to "collapse" unused ports in the guard tree to ports out a constant cell outputting an n-bit 0 signal. I remember trying to figure out how I should modify the guard of the existing component; I ended up trying (from what I can tell) all three ways, with minimal initial success. From within guard.rs, I created three functions, each called some variant of Unfortunately, it looks like I couldn't stick by the personal deadline I made last week to try and have PR done by this weekend. But I will keep at it! I feel like I'm learning a lot; even if this pass turns out to be not super helpful or is too cost inefficient, it's still very cool to reason about, especially given Rust's type system :) |
Beta Was this translation helpful? Give feedback.
-
Here's a question (relevant to the unused-port-removal optimization) that I don't quite know the answer to. In a Calyx program, for which ports are we allowed to assume that undriven => 0? (And the flip side of this, when should we assume undriven => ’x?). I've read #1169 but It's still not quite clear to me. More concretely, suppose we have a component:
Suppose that in our main, we have a group:
When we are executing the group g1 inside of Q :
are we allowed to assume In general, it seems that almost any use of Q will be marked as a One final question: suppose we had the following group inside of Q :
Does that affect whether or not we are allowed to assume |
Beta Was this translation helpful? Give feedback.
-
We have a question about the following Calyx program: Example Program
QuestionFor this group:
During execution of this group, are the values for
we get an error ( However, if we change it to:
then we don't get an error, and we get the expected results. Note also that we Data File for reproduction purposes(we expect 1 to be in the final memory in place of 89)
|
Beta Was this translation helpful? Give feedback.
-
Hey! Thought I'd present an update even though we've been having pretty consistent discussions. So from my understanding), I think I've gotten down the basic functionality of
I wrote a couple of designs, and I'm pretty sure they do exactly as intended! But, as we saw above, one specific design seems to have brought certain issues to light. There was a big thread about it in the Calyx Slack channel, and Caleb and I discussed it at length on Wednesday's Calyx-opt meeting. We were fairly certain something was up because one of the components we designed was marked as After looking into it, it seemed to be something to do with the fact that some input ports were not driven (since we needed to test Based on the emails I'm receiving after I commit, I'm still failing out on formatting and some tests. But we can bang those issues out at Calyx-opt. Thanks! |
Beta Was this translation helpful? Give feedback.
-
Hello! Sorry for the delayed update, it has been a packed couple of weeks haha. This discussion will mainly serve as a summary of the Calyx meeting around #1960 (planning the performance dashboard). In that meeting, we discussed:
That's all! I plan to make a PR on |
Beta Was this translation helpful? Give feedback.
-
Quick updates! This week, I worked on compiling Calyx designs to be used as benchmarks on the performance dashboard, and I worked on a script to take these benchmarks and get a summary primitive usage (see this commit, apologies for the strange message formatting). A couple open comments / questions on this first attempt at benchmark summary:
That's all! Thanks! |
Beta Was this translation helpful? Give feedback.
-
Hello! Some updates and questions: Following the AMC/Opt meeting a couple weeks ago, @calebmkim and I started working on some FSM optimizations in Calyx after hearing about how an equivalent Vitis design generated significantly lower LUT usage. Right now, I'm using the work that Caleb did to separate the Static FSM object and implementing one hot encoding (OHE) to see if that helps. Here are the steps I've taken so far and things left to do:
Unfortunately, it's looking like it won't be done in time for the next AMC/Opt meeting because of the blocker mentioned above. But, I'm looking to get it fixed by meeting in-person tomorrow and to keep going after! Some open, brain-dump comments/questions:
Thanks!! |
Beta Was this translation helpful? Give feedback.
-
Lab notebook for questions/updates on Calyx-Opt
Beta Was this translation helpful? Give feedback.
All reactions