-
Notifications
You must be signed in to change notification settings - Fork 772
mpl: enumerate tilings for macro clusters instead of using simulated annealing #9247
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
mpl: enumerate tilings for macro clusters instead of using simulated annealing #9247
Conversation
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
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.
Code Review
This pull request is a great simplification, replacing the Simulated Annealing approach for macro tiling with a more direct and deterministic enumeration method. This should lead to more predictable and optimal results for macro cluster shapes. The removal of the size_tolerance variable is also a good cleanup, making the clustering thresholds more reliable. I have a few suggestions to improve the implementation further, mainly focusing on performance, robustness, and code clarity.
| return; | ||
| } | ||
| int number_of_macros = hard_macros.size(); | ||
| int macro_width = hard_macros.front()->getWidth(); |
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.
There's a potential for a crash here if cluster->getHardMacros() returns an empty vector, as hard_macros.front() would be undefined behavior. Although the call chain seems to prevent this, adding a defensive check for an empty vector would make the code more robust. For example:
std::vector<HardMacro*> hard_macros = cluster->getHardMacros();
if (hard_macros.empty()) {
return;
}
int number_of_macros = hard_macros.size();
// ...
src/mpl/src/hier_rtlmp.cpp
Outdated
| if (tilings.size() == 0) { | ||
| TilingList extra_tilings = generateTilingsForMacroCluster( | ||
| macro_width, macro_height, number_of_macros + 1); | ||
| tilings.insert(tilings.end(), extra_tilings.begin(), extra_tilings.end()); | ||
| } |
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.
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.
clang-tidy made some suggestions
src/mpl/src/hier_rtlmp.cpp
Outdated
| } | ||
| } | ||
| remaining_runs -= run_thread; | ||
| if (tilings.size() == 0) { |
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.
warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
| if (tilings.size() == 0) { | |
| if (tilings.empty()) { |
Additional context
/usr/include/c++/13/bits/stl_vector.h:1087: method 'vector'::empty() defined here
empty() const _GLIBCXX_NOEXCEPT
^
src/mpl/src/hier_rtlmp.cpp
Outdated
| } | ||
|
|
||
| if (tilings_set.empty()) { | ||
| if (tilings.size() == 0) { |
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.
warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
| if (tilings.size() == 0) { | |
| if (tilings.empty()) { |
Additional context
/usr/include/c++/13/bits/stl_vector.h:1087: method 'vector'::empty() defined here
empty() const _GLIBCXX_NOEXCEPT
^Signed-off-by: João Mai <jmai@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
|
Paired with PR #3781 on ORFS. |
|
Secure CI is ok, public CI has some fails that are addressed in the ORFS PR. |
AcKoucher
left a comment
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.
Nice!
src/mpl/src/hier_rtlmp.cpp
Outdated
| TilingList extra_tilings = generateTilingsForMacroCluster( | ||
| macro_width, macro_height, number_of_macros + 1); | ||
| tilings.insert(tilings.end(), extra_tilings.begin(), extra_tilings.end()); |
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.
No need for std::vector::insert here. Just assign tilings directly.
Signed-off-by: João Mai <jmai@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
AcKoucher
left a comment
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.
LGTM.
| if (number_of_macros % cols == 0) { | ||
| rows = number_of_macros / cols; |
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.
If we only allow perfect tiling we will have more limited choices (e.g. for an 9 macros you won't try 2x5, only 1x9 and 3x3). Is this intentional?
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.
Yes. The previous code kept only the smallest area tilings too. Doing it this way also avoids notches.
| } | ||
| int number_of_macros = hard_macros.size(); | ||
| int macro_width = hard_macros.front()->getWidth(); | ||
| int macro_height = hard_macros.front()->getHeight(); |
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.
Where does this check that all macros are of a single master? What if they are not?
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 clusters are always made of macros of the same size. The function that creates/merges macro clusters checks for their sizes (ClusteringEngine::groupSingleMacroCluster using the size_class variable).
This PR changes the behavior of the calculaMacroTilings function. Now, the function enumerates the possible tilings for a given cluster instead of using SA to find the tilings. This enables tighter results, since the generated options are guaranteed to be minimum area.
This PR also removes the size_tolerance variable. It was used to change the maximum and minimum values for the thresholds, reducing the minimum and increasing the maximum. In practice, it made the use o MPL thresholds variables unreliable, with the only justification being a comment saying that it made the macro placer "more robust".