-
Notifications
You must be signed in to change notification settings - Fork 986
In the ABC pass, avoid scanning the entire module for each ABC run #5239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
243726b
to
cbd3400
Compare
I'm considering doing this in a different way. |
cbd3400
to
2fb2d08
Compare
So I ended up doing this part in a different way. I introduce a Then, when we need to determine which signals are ports for a specific cell partition, we can basically just lookup that flag. We do also need to take into account that some cells in a partition may be rejected and not passed to ABC (I call them the "kept cells") --- connections to those cells need to be treated as ports as well. (I made this change because I have another PR in the works which runs the ABC runs in parallel. For that to work, we have to be able to |
2fb2d08
to
a54a673
Compare
Just out of curiosity, do you mean you call Yosys' I think it is the former but then my questions are:
|
This. |
I discovered another "scan the whole module per ABC run", constructing |
@widlarizer This one provides quite a large speedup on some of our workloads could we prioritize getting this reviewed and merged? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assign_map change looks good (assign_map needs to be updated when and only when adding module connections)
the wires don't meaningfully change
Could you be more specific?
Also, the refactor is very welcome, thanks |
…odules to an `AbcConfig` struct.
…ion `extract()` Splits up the big `abc_module()` function and isolates the code that modifies the design after running ABC.
c0967c4
to
2336027
Compare
|
Currently `assign_map` is rebuilt from the module from scratch every time we invoke ABC. That doesn't scale when we do thousands of ABC runs over large modules. Instead, create it once and then maintain incrementally it as we update the module.
…wires in the module every time we run ABC. This does not scale when we run ABC thousands of times in a single AbcPass.
2336027
to
62c4411
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constructing FfInitVals requires iterating over all module wires, and we were constructing one of these in every ABC run
Looking at main, I don't think this is the case. This happens per module and no other initvals.set
happens:
assign_map.set(mod);
initvals.set(&assign_map, mod);
As far as I can tell, the unnecessary initvals rebuild per abc_module
call snuck in while refactoring, which is fine, it just threw me for a bit of a loop reviewing this
Oops, sorry. Thanks for clarifying that. |
What are the reasons/motivation for this change?
We have some large modules where a single ABC pass runs ABC thousands of times. The pass is very slow because in a couple of places it scans the entire module each time it runs ABC. Without too much work we can avoid this and get significant speedups. For example on one of our real-world examples this PR speeds up the ABC pass by 6x.
Explain how this is achieved.
One problem is rebuilding
assign_map
from scratch for every ABC call. Instead we can build it once and maintain it incrementally as the module is modified.Another problem is scanning all module wires and cells to call
mark_port()
. This is a bit trickier; we need to introduce a reverse map from canonicalSigBit
s to the module wires and cells associated with each bit, and maintain that as the module is modified.Another problem is that constructing
FfInitVals
requires iterating over all module wires, and we were constructing one of these in every ABC run. We don't really need to, because the wires don't meaningfully change during this pass. So just construct a singleFfInitVals
for the module and use it for all ABC runs.The use of global variables and the very large
abc_module()
function make things a bit less clear than they need to be, so I started off the PR by cleaning that up a bit.If applicable, please suggest to reviewers how they can test the change.
This PR is intended to not change results at all, and in my limited testing it doesn't. I have checked that some of our very large circuits are not affected by this PR.